From 1aaa39353d9681d4fe6d9b3889630a042cc3aa28 Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Sat, 7 Dec 2024 03:26:59 +0100 Subject: [PATCH 01/14] v0.13.0-alpha.1 - see CHANGELOG for details --- .gitignore | 1 + CHANGELOG.md | 8 + deno.json | 18 ++ deno.lock | 181 ++++++++++++++++++ dev_deps.ts | 41 ---- jsr.json | 3 +- mod.ts | 10 +- src/Controller.ts | 19 +- src/ControllerMethodArgs.ts | 50 +++-- src/ControllerMethodArgs_test.ts | 24 ++- src/Delete.ts | 27 ++- src/Delete_test.ts | 5 +- src/Get.ts | 27 ++- src/Get_test.ts | 5 +- src/Head.ts | 27 ++- src/Head_test.ts | 5 +- src/Options.ts | 27 ++- src/Options_test.ts | 5 +- src/Patch.ts | 27 ++- src/Patch_test.ts | 5 +- src/Post.ts | 27 ++- src/Post_test.ts | 5 +- src/Put.ts | 27 ++- src/Put_test.ts | 5 +- src/Store_test.ts | 8 +- src/oasStore.ts | 3 +- src/oasStore_test.ts | 5 +- src/useOakServer.ts | 8 +- src/useOakServer_test.ts | 16 +- src/useOas.ts | 18 +- src/useOas_test.ts | 17 +- ...getUserSuppliedDecoratedMethodName_test.ts | 2 +- src/utils/inspect_test.ts | 2 +- src/utils/logger_test.ts | 9 +- deps.ts => src/utils/schema_utils.ts | 45 ++--- test_utils/mockRequestInternals.ts | 2 +- 36 files changed, 514 insertions(+), 200 deletions(-) create mode 100644 deno.json create mode 100644 deno.lock delete mode 100644 dev_deps.ts rename deps.ts => src/utils/schema_utils.ts (79%) diff --git a/.gitignore b/.gitignore index 4cbe51f..221d00a 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ Temporary Items cov_profile cov_profile.lcov +docs diff --git a/CHANGELOG.md b/CHANGELOG.md index 7da13cb..ef9ea60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## Unreleased + +### Changed + +- switched from `deps.ts` and `dev_deps.ts` to `deno.jsonc` +- revamped documentation +- code format + ## [0.12.2] - 2024-12-06 ### Added diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..4b24d57 --- /dev/null +++ b/deno.json @@ -0,0 +1,18 @@ +{ + "imports": { + "@asteasolutions/zod-to-openapi": "npm:@asteasolutions/zod-to-openapi@^7.3.0", + "@dklab/oak-routing-ctrl": "jsr:@dklab/oak-routing-ctrl@^0.12.2", + "@oak/oak": "jsr:@oak/oak@^17.1.3", + "@std/assert": "jsr:@std/assert@^1.0.9", + "@std/io": "jsr:@std/io@^0.225.0", + "@std/path": "jsr:@std/path@^1.0.8", + "@std/testing": "jsr:@std/testing@^1.0.6", + "zod": "npm:zod@^3.23.8" + }, + "tasks": { + "pretty": "deno lint --ignore=docs && deno check . && deno fmt", + "test": "deno test -RE", + "check-doc": "deno check --doc .", + "doc": "deno doc --html mod.ts" + } +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..f456297 --- /dev/null +++ b/deno.lock @@ -0,0 +1,181 @@ +{ + "version": "4", + "specifiers": { + "jsr:@dklab/oak-routing-ctrl@~0.12.2": "0.12.2", + "jsr:@oak/commons@1": "1.0.0", + "jsr:@oak/oak@^17.1.3": "17.1.3", + "jsr:@std/assert@1": "1.0.9", + "jsr:@std/assert@^1.0.7": "1.0.9", + "jsr:@std/assert@^1.0.9": "1.0.9", + "jsr:@std/bytes@1": "1.0.4", + "jsr:@std/bytes@^1.0.2": "1.0.4", + "jsr:@std/crypto@1": "1.0.3", + "jsr:@std/data-structures@^1.0.4": "1.0.4", + "jsr:@std/encoding@1": "1.0.5", + "jsr:@std/encoding@^1.0.5": "1.0.5", + "jsr:@std/fs@^1.0.6": "1.0.6", + "jsr:@std/http@1": "1.0.12", + "jsr:@std/internal@^1.0.5": "1.0.5", + "jsr:@std/io@0.224": "0.224.9", + "jsr:@std/io@0.225": "0.225.0", + "jsr:@std/media-types@1": "1.1.0", + "jsr:@std/path@1": "1.0.8", + "jsr:@std/path@^1.0.8": "1.0.8", + "jsr:@std/testing@^1.0.4": "1.0.6", + "jsr:@std/testing@^1.0.6": "1.0.6", + "npm:@asteasolutions/zod-to-openapi@^7.2.0": "7.2.0_zod@3.23.8", + "npm:@asteasolutions/zod-to-openapi@^7.3.0": "7.3.0_zod@3.23.8", + "npm:@types/node@*": "22.5.4", + "npm:path-to-regexp@6.2.1": "6.2.1", + "npm:zod@^3.23.8": "3.23.8" + }, + "jsr": { + "@dklab/oak-routing-ctrl@0.12.2": { + "integrity": "ffafb942871916d2aeb685403069dc2155fa2dc070b41235aa39ad6074ee617b", + "dependencies": [ + "jsr:@oak/oak", + "jsr:@std/path@^1.0.8", + "npm:@asteasolutions/zod-to-openapi@^7.2.0", + "npm:zod" + ] + }, + "@oak/commons@1.0.0": { + "integrity": "49805b55603c3627a9d6235c0655aa2b6222d3036b3a13ff0380c16368f607ac", + "dependencies": [ + "jsr:@std/assert@1", + "jsr:@std/bytes@1", + "jsr:@std/crypto", + "jsr:@std/encoding@1", + "jsr:@std/http", + "jsr:@std/media-types" + ] + }, + "@oak/oak@17.1.3": { + "integrity": "d89296c22db91681dd3a2a1e1fd14e258d0d5a9654de55637aee5b661c159f33", + "dependencies": [ + "jsr:@oak/commons", + "jsr:@std/assert@1", + "jsr:@std/bytes@1", + "jsr:@std/crypto", + "jsr:@std/http", + "jsr:@std/io@0.224", + "jsr:@std/media-types", + "jsr:@std/path@1", + "npm:path-to-regexp" + ] + }, + "@std/assert@1.0.9": { + "integrity": "a9f0c611a869cc791b26f523eec54c7e187aab7932c2c8e8bea0622d13680dcd", + "dependencies": [ + "jsr:@std/internal" + ] + }, + "@std/bytes@1.0.4": { + "integrity": "11a0debe522707c95c7b7ef89b478c13fb1583a7cfb9a85674cd2cc2e3a28abc" + }, + "@std/crypto@1.0.3": { + "integrity": "a2a32f51ddef632d299e3879cd027c630dcd4d1d9a5285d6e6788072f4e51e7f" + }, + "@std/data-structures@1.0.4": { + "integrity": "fa0e20c11eb9ba673417450915c750a0001405a784e2a4e0c3725031681684a0" + }, + "@std/encoding@1.0.5": { + "integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04" + }, + "@std/fs@1.0.6": { + "integrity": "42b56e1e41b75583a21d5a37f6a6a27de9f510bcd36c0c85791d685ca0b85fa2", + "dependencies": [ + "jsr:@std/path@^1.0.8" + ] + }, + "@std/http@1.0.12": { + "integrity": "85246d8bfe9c8e2538518725b158bdc31f616e0869255f4a8d9e3de919cab2aa", + "dependencies": [ + "jsr:@std/encoding@^1.0.5" + ] + }, + "@std/internal@1.0.5": { + "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba" + }, + "@std/io@0.224.9": { + "integrity": "4414664b6926f665102e73c969cfda06d2c4c59bd5d0c603fd4f1b1c840d6ee3", + "dependencies": [ + "jsr:@std/bytes@^1.0.2" + ] + }, + "@std/io@0.225.0": { + "integrity": "c1db7c5e5a231629b32d64b9a53139445b2ca640d828c26bf23e1c55f8c079b3", + "dependencies": [ + "jsr:@std/bytes@^1.0.2" + ] + }, + "@std/media-types@1.1.0": { + "integrity": "c9d093f0c05c3512932b330e3cc1fe1d627b301db33a4c2c2185c02471d6eaa4" + }, + "@std/path@1.0.8": { + "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be" + }, + "@std/testing@1.0.6": { + "integrity": "9192ded2d34065f4c959fdc1921fe836770abb9194410c2cc8a0fff4eff5c893", + "dependencies": [ + "jsr:@std/assert@^1.0.9", + "jsr:@std/data-structures", + "jsr:@std/fs", + "jsr:@std/internal", + "jsr:@std/path@^1.0.8" + ] + } + }, + "npm": { + "@asteasolutions/zod-to-openapi@7.2.0_zod@3.23.8": { + "integrity": "sha512-Va+Fq1QzKkSgmiYINSp3cASFhMsbdRH/kmCk2feijhC+yNjGoC056CRqihrVFhR8MY8HOZHdlYm2Ns2lmszCiw==", + "dependencies": [ + "openapi3-ts", + "zod" + ] + }, + "@asteasolutions/zod-to-openapi@7.3.0_zod@3.23.8": { + "integrity": "sha512-7tE/r1gXwMIvGnXVUdIqUhCU1RevEFC4Jk6Bussa0fk1ecbnnINkZzj1EOAJyE/M3AI25DnHT/zKQL1/FPFi8Q==", + "dependencies": [ + "openapi3-ts", + "zod" + ] + }, + "@types/node@22.5.4": { + "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "dependencies": [ + "undici-types" + ] + }, + "openapi3-ts@4.4.0": { + "integrity": "sha512-9asTNB9IkKEzWMcHmVZE7Ts3kC9G7AFHfs8i7caD8HbI76gEjdkId4z/AkP83xdZsH7PLAnnbl47qZkXuxpArw==", + "dependencies": [ + "yaml" + ] + }, + "path-to-regexp@6.2.1": { + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + }, + "undici-types@6.19.8": { + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + }, + "yaml@2.6.1": { + "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==" + }, + "zod@3.23.8": { + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==" + } + }, + "workspace": { + "dependencies": [ + "jsr:@dklab/oak-routing-ctrl@~0.12.2", + "jsr:@oak/oak@^17.1.3", + "jsr:@std/assert@^1.0.9", + "jsr:@std/io@0.225", + "jsr:@std/path@^1.0.8", + "jsr:@std/testing@^1.0.6", + "npm:@asteasolutions/zod-to-openapi@^7.3.0", + "npm:zod@^3.23.8" + ] + } +} diff --git a/dev_deps.ts b/dev_deps.ts deleted file mode 100644 index f65be58..0000000 --- a/dev_deps.ts +++ /dev/null @@ -1,41 +0,0 @@ -export { - assert, - assertEquals, - assertInstanceOf, - assertObjectMatch, - assertStringIncludes, - assertThrows, -} from "jsr:@std/assert@^1.0.7"; - -export { - type BodyType, - type Middleware, - Request, - testing as oakTesting, -} from "jsr:@oak/oak@^17.1.3"; - -export { Body } from "jsr:@oak/oak@^17.1.3/body"; - -export { - assertSpyCall, - assertSpyCallArg, - assertSpyCalls, - type MethodSpy, - type Spy, - spy, - type Stub, - stub, -} from "jsr:@std/testing@^1.0.4/mock"; - -export { assertSnapshot } from "jsr:@std/testing@^1.0.4/snapshot"; - -export { Buffer } from "jsr:@std/io@^0.225.0"; - -export { - afterEach, - beforeEach, - describe, - it, -} from "jsr:@std/testing@^1.0.4/bdd"; - -export { ZodObject } from "npm:zod@^3.23.8"; diff --git a/jsr.json b/jsr.json index 2acb861..868a522 100644 --- a/jsr.json +++ b/jsr.json @@ -1,11 +1,12 @@ { "name": "@dklab/oak-routing-ctrl", - "version": "0.12.2", + "version": "0.13.0", "exports": { ".": "./mod.ts", "./mod": "./mod.ts" }, "exclude": [ + "./docs", "./test_utils", "**/*_test.ts", "cov_profile", diff --git a/mod.ts b/mod.ts index b644165..078ffb7 100644 --- a/mod.ts +++ b/mod.ts @@ -1,6 +1,6 @@ export { useOakServer } from "./src/useOakServer.ts"; -export { useOakServer as useOak } from "./src/useOakServer.ts"; -export { useOas } from "./src/useOas.ts"; +export { useOak } from "./src/useOakServer.ts"; +export { useOas, type UseOasConfig } from "./src/useOas.ts"; export { Controller } from "./src/Controller.ts"; export { type ControllerMethodArg, @@ -14,4 +14,8 @@ export { Delete } from "./src/Delete.ts"; export { Options } from "./src/Options.ts"; export { Head } from "./src/Head.ts"; -export { type OakOpenApiSpec, z, type zInfer } from "./deps.ts"; +export { + type OakOpenApiSpec, + z, + type zInfer, +} from "./src/utils/schema_utils.ts"; diff --git a/src/Controller.ts b/src/Controller.ts index 6d108c9..a9d0e87 100644 --- a/src/Controller.ts +++ b/src/Controller.ts @@ -1,20 +1,31 @@ +import { join } from "@std/path"; import { debug } from "./utils/logger.ts"; -import { join } from "../deps.ts"; import { store } from "./Store.ts"; import { patchOasPath } from "./oasStore.ts"; /** - * Just a standard Class, that can be decorated with the `@Controller` decorator + * Just a standard Class, that can be decorated with the {@linkcode Controller} decorator */ export type ControllerClass = new (args?: unknown) => unknown; +type ClassDecorator = ( + target: ControllerClass, + context?: ClassDecoratorContext, +) => void; + /** * Decorator that should be used on the Controller Class * @NOTE under `experimentalDecorators`, `context` is not available + * @example + * ```ts + * ;@Controller("/api/") + * class ExampleClass { + * // functions that handle endpoints starting with `/api/` + * } + * ``` */ export const Controller = - (pathPrefix: string = "") => - (target: ControllerClass, context?: ClassDecoratorContext): void => { + (pathPrefix: string = ""): ClassDecorator => (target, context): void => { debug( `invoking ControllerDecorator for ${target.name} -`, "runtime provides context:", diff --git a/src/ControllerMethodArgs.ts b/src/ControllerMethodArgs.ts index 8276c78..ab28b19 100644 --- a/src/ControllerMethodArgs.ts +++ b/src/ControllerMethodArgs.ts @@ -1,16 +1,18 @@ import { debug } from "./utils/logger.ts"; -import { type Context, type RouteContext } from "../deps.ts"; +import { type Context, type RouteContext } from "@oak/oak"; import { ERR_UNSUPPORTED_CLASS_METHOD_DECORATOR_RUNTIME_BEHAVIOR } from "./Constants.ts"; /** - * literal keywords that can be used as arguments for the `@ControllerMethodArgs` + * literal keywords that can be used as arguments for the {@linkcode ControllerMethodArgs} * decorator; these keywords **MUST** appear in the same order that their counterpart * arguments show up in the actual (decorated) handler function * @example * ```ts - * (@)ControllerMethodArgs("query", "body") - * doSomething(query, body) { - * console.log(query, body); + * class ExampleClass { + * ;@ControllerMethodArgs("query", "body") + * doSomething(query: object, body: object) { + * console.log(query, body); + * } * } * ``` */ @@ -27,36 +29,44 @@ type EnhancedHandler = ( ...args: unknown[] ) => Promise; +type MethodDecorator = ( + // deno-lint-ignore ban-types + arg1: Function | object, + arg2: ClassMethodDecoratorContext | string, + // deno-lint-ignore no-explicit-any + ...rest: any[] + // deno-lint-ignore no-explicit-any +) => any; + /** * Decorator that should be used on the Controller Method * when we need to refer to the request body, param, query, etc. * in the Method Body * @returns a function with the signature (arguments) matching that * of the provided `desirableParams`, which can then be **decorated** - * with one of the Class Method decorators (e.g. `Get`, `Post`, etc.) + * with one of the Class Method decorators (e.g. {@linkcode Get}, {@linkcode Post}, etc.) * @example - * ```ts - * (@)Controller("/api/v1") + * ``` + * import { Controller, Post, ControllerMethodArgs } from "@dklab/oak-routing-ctrl" + * + * ;@Controller() * class MyClass { - * (@)Post("/:resource") - * (@)ControllerMethodArgs("body", "query", "param") - * doSomething(body, query, param, ctx): void { + * ;@Post("/:resource") + * ;@ControllerMethodArgs("body", "query", "param", "headers") + * doSomething(body, query, param, headers, ctx): void { * console.log(`endpoint called: /api/v1/${ctx.params.resource}`); - * console.log(`now let's do something with`, body, query, param); + * console.log(`now let's do something with`, body, query, param, headers); * } * } * ``` */ export const ControllerMethodArgs = - (...desirableParams: ControllerMethodArg[]) => + (...desirableParams: ControllerMethodArg[]): MethodDecorator => ( - // deno-lint-ignore ban-types - arg1: Function | object, - arg2: ClassMethodDecoratorContext | string, - // deno-lint-ignore no-explicit-any - ...rest: any[] - // deno-lint-ignore no-explicit-any - ): any => { + arg1, + arg2, + ...rest + ) => { if (typeof arg1 === "function" && typeof arg2 === "object") { return decorateClassMethodTypeStandard( arg1, diff --git a/src/ControllerMethodArgs_test.ts b/src/ControllerMethodArgs_test.ts index f550b88..bba4517 100644 --- a/src/ControllerMethodArgs_test.ts +++ b/src/ControllerMethodArgs_test.ts @@ -1,14 +1,26 @@ +import { type BodyType, testing as oakTesting } from "@oak/oak"; +import { Body } from "@oak/oak/body"; import { assertEquals, - assertSpyCalls, + // assertSpyCalls, assertStringIncludes, assertThrows, - Body, - type BodyType, - Buffer, - oakTesting, + // Body, + // type BodyType, + // Buffer, + // oakTesting, + // spy, +} from "@std/assert"; +import { + // assertEquals, + assertSpyCalls, + // assertStringIncludes, + // assertThrows, + // Body, + // type BodyType, spy, -} from "../dev_deps.ts"; +} from "@std/testing/mock"; +import { Buffer } from "@std/io"; import { ERR_UNSUPPORTED_CLASS_METHOD_DECORATOR_RUNTIME_BEHAVIOR } from "./Constants.ts"; import { _internal, diff --git a/src/Delete.ts b/src/Delete.ts index 9fae93a..039885a 100644 --- a/src/Delete.ts +++ b/src/Delete.ts @@ -1,19 +1,36 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "../deps.ts"; +import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; +type MethodDecorator = ( + // deno-lint-ignore ban-types + arg1: Function | object, + arg2: ClassMethodDecoratorContext | string, +) => void; + /** * Decorator that should be used on the Controller Class Method - * for DELETE endpoints + * for `DELETE` endpoints + * @example + * ```ts + * import { Controller, Delete } from "@dklab/oak-routing-ctrl" + * + * ;@Controller() + * class ExampleClass { + * ;@Delete("/:resource") + * async deleteSomething() { + * // implementation + * } + * } + * ``` */ export const Delete = ( path: string = "", openApiSpec?: OakOpenApiSpec, -) => -// deno-lint-ignore ban-types -(arg1: Function | object, arg2: ClassMethodDecoratorContext | string): void => { +): MethodDecorator => +(arg1, arg2): void => { const fnName: string = getUserSuppliedDecoratedMethodName(arg1, arg2); debug( `invoking Delete MethodDecorator for ${fnName} with pathPrefix ${path} -`, diff --git a/src/Delete_test.ts b/src/Delete_test.ts index ba99825..20f4ab8 100644 --- a/src/Delete_test.ts +++ b/src/Delete_test.ts @@ -1,11 +1,10 @@ +import { assertEquals, assertInstanceOf } from "@std/assert"; import { - assertEquals, - assertInstanceOf, assertSpyCall, assertSpyCalls, type MethodSpy, spy, -} from "../dev_deps.ts"; +} from "@std/testing/mock"; import { store } from "./Store.ts"; import { _internal } from "./Delete.ts"; diff --git a/src/Get.ts b/src/Get.ts index 4368081..2e642d2 100644 --- a/src/Get.ts +++ b/src/Get.ts @@ -1,19 +1,36 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "../deps.ts"; +import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; +type MethodDecorator = ( + // deno-lint-ignore ban-types + arg1: Function | object, + arg2: ClassMethodDecoratorContext | string, +) => void; + /** * Decorator that should be used on the Controller Class Method - * for GET endpoints + * for `GET` endpoints + * @example + * ```ts + * import { Controller, Get } from "@dklab/oak-routing-ctrl" + * + * ;@Controller() + * class ExampleClass { + * ;@Get("/") + * async retrieveSomething() { + * // implementation + * } + * } + * ``` */ export const Get = ( path: string = "", openApiSpec?: OakOpenApiSpec, -) => -// deno-lint-ignore ban-types -(arg1: Function | object, arg2: ClassMethodDecoratorContext | string): void => { +): MethodDecorator => +(arg1, arg2): void => { const fnName: string = getUserSuppliedDecoratedMethodName(arg1, arg2); debug( `invoking Get MethodDecorator for ${fnName} with pathPrefix ${path} -`, diff --git a/src/Get_test.ts b/src/Get_test.ts index 822d52c..3d6f599 100644 --- a/src/Get_test.ts +++ b/src/Get_test.ts @@ -1,11 +1,10 @@ +import { assertEquals, assertInstanceOf } from "@std/assert"; import { - assertEquals, - assertInstanceOf, assertSpyCall, assertSpyCalls, type MethodSpy, spy, -} from "../dev_deps.ts"; +} from "@std/testing/mock"; import { store } from "./Store.ts"; import { _internal } from "./Get.ts"; diff --git a/src/Head.ts b/src/Head.ts index b8ca4b5..b2942df 100644 --- a/src/Head.ts +++ b/src/Head.ts @@ -1,19 +1,36 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "../deps.ts"; +import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; +type MethodDecorator = ( + // deno-lint-ignore ban-types + arg1: Function | object, + arg2: ClassMethodDecoratorContext | string, +) => void; + /** * Decorator that should be used on the Controller Class Method - * for HEAD endpoints + * for `HEAD` endpoints + * @example + * ```ts + * import { Controller, Head } from "@dklab/oak-routing-ctrl" + * + * ;@Controller() + * class ExampleClass { + * ;@Head("/") + * async lookupSomething() { + * // implementation + * } + * } + * ``` */ export const Head = ( path: string = "", openApiSpec?: OakOpenApiSpec, -) => -// deno-lint-ignore ban-types -(arg1: Function | object, arg2: ClassMethodDecoratorContext | string): void => { +): MethodDecorator => +(arg1, arg2): void => { const fnName: string = getUserSuppliedDecoratedMethodName(arg1, arg2); debug( `invoking Head MethodDecorator for ${fnName} with pathPrefix ${path} -`, diff --git a/src/Head_test.ts b/src/Head_test.ts index 9268360..533af72 100644 --- a/src/Head_test.ts +++ b/src/Head_test.ts @@ -1,11 +1,10 @@ +import { assertEquals, assertInstanceOf } from "@std/assert"; import { - assertEquals, - assertInstanceOf, assertSpyCall, assertSpyCalls, type MethodSpy, spy, -} from "../dev_deps.ts"; +} from "@std/testing/mock"; import { store } from "./Store.ts"; import { _internal } from "./Head.ts"; diff --git a/src/Options.ts b/src/Options.ts index bf433a5..2f578a1 100644 --- a/src/Options.ts +++ b/src/Options.ts @@ -1,19 +1,36 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "../deps.ts"; +import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; +type MethodDecorator = ( + // deno-lint-ignore ban-types + arg1: Function | object, + arg2: ClassMethodDecoratorContext | string, +) => void; + /** * Decorator that should be used on the Controller Class Method - * for OPTIONS endpoints + * for `OPTIONS` endpoints + * @example + * ```ts + * import { Controller, Options } from "@dklab/oak-routing-ctrl" + * + * ;@Controller() + * class ExampleClass { + * ;@Options("/") + * async doSomething() { + * // implementation + * } + * } + * ``` */ export const Options = ( path: string = "", openApiSpec?: OakOpenApiSpec, -) => -// deno-lint-ignore ban-types -(arg1: Function | object, arg2: ClassMethodDecoratorContext | string): void => { +): MethodDecorator => +(arg1, arg2): void => { const fnName: string = getUserSuppliedDecoratedMethodName(arg1, arg2); debug( `invoking Options MethodDecorator for ${fnName} with pathPrefix ${path} -`, diff --git a/src/Options_test.ts b/src/Options_test.ts index 042c79f..9a9aab1 100644 --- a/src/Options_test.ts +++ b/src/Options_test.ts @@ -1,11 +1,10 @@ +import { assertEquals, assertInstanceOf } from "@std/assert"; import { - assertEquals, - assertInstanceOf, assertSpyCall, assertSpyCalls, type MethodSpy, spy, -} from "../dev_deps.ts"; +} from "@std/testing/mock"; import { store } from "./Store.ts"; import { _internal } from "./Options.ts"; diff --git a/src/Patch.ts b/src/Patch.ts index 9e5f04f..9506a65 100644 --- a/src/Patch.ts +++ b/src/Patch.ts @@ -1,19 +1,36 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "../deps.ts"; +import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; +type MethodDecorator = ( + // deno-lint-ignore ban-types + arg1: Function | object, + arg2: ClassMethodDecoratorContext | string, +) => void; + /** * Decorator that should be used on the Controller Class Method - * for PATCH endpoints + * for `PATCH` endpoints + * @example + * ```ts + * import { Controller, Patch } from "@dklab/oak-routing-ctrl" + * + * ;@Controller() + * class ExampleClass { + * ;@Patch("/") + * async adjustSomething() { + * // implementation + * } + * } + * ``` */ export const Patch = ( path: string = "", openApiSpec?: OakOpenApiSpec, -) => -// deno-lint-ignore ban-types -(arg1: Function | object, arg2: ClassMethodDecoratorContext | string): void => { +): MethodDecorator => +(arg1, arg2): void => { const fnName: string = getUserSuppliedDecoratedMethodName(arg1, arg2); debug( `invoking Patch MethodDecorator for ${fnName} with pathPrefix ${path} -`, diff --git a/src/Patch_test.ts b/src/Patch_test.ts index eb8d2d0..7f7b086 100644 --- a/src/Patch_test.ts +++ b/src/Patch_test.ts @@ -1,11 +1,10 @@ +import { assertEquals, assertInstanceOf } from "@std/assert"; import { - assertEquals, - assertInstanceOf, assertSpyCall, assertSpyCalls, type MethodSpy, spy, -} from "../dev_deps.ts"; +} from "@std/testing/mock"; import { store } from "./Store.ts"; import { _internal } from "./Patch.ts"; diff --git a/src/Post.ts b/src/Post.ts index bbff422..f2f1c41 100644 --- a/src/Post.ts +++ b/src/Post.ts @@ -1,19 +1,36 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "../deps.ts"; +import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; +type MethodDecorator = ( + // deno-lint-ignore ban-types + arg1: Function | object, + arg2: ClassMethodDecoratorContext | string, +) => void; + /** * Decorator that should be used on the Controller Class Method - * for POST endpoints + * for `POST` endpoints + * @example + * ```ts + * import { Controller, Post } from "@dklab/oak-routing-ctrl" + * + * ;@Controller() + * class ExampleClass { + * ;@Post("/") + * async updateSomething() { + * // implementation + * } + * } + * ``` */ export const Post = ( path: string = "", openApiSpec?: OakOpenApiSpec, -) => -// deno-lint-ignore ban-types -(arg1: Function | object, arg2: ClassMethodDecoratorContext | string): void => { +): MethodDecorator => +(arg1, arg2): void => { const fnName: string = getUserSuppliedDecoratedMethodName(arg1, arg2); debug( `invoking Post MethodDecorator for ${fnName} with pathPrefix ${path} -`, diff --git a/src/Post_test.ts b/src/Post_test.ts index f42d63c..d3314c4 100644 --- a/src/Post_test.ts +++ b/src/Post_test.ts @@ -1,11 +1,10 @@ +import { assertEquals, assertInstanceOf } from "@std/assert"; import { - assertEquals, - assertInstanceOf, assertSpyCall, assertSpyCalls, type MethodSpy, spy, -} from "../dev_deps.ts"; +} from "@std/testing/mock"; import { store } from "./Store.ts"; import { _internal } from "./Post.ts"; diff --git a/src/Put.ts b/src/Put.ts index 1706fd7..09ab053 100644 --- a/src/Put.ts +++ b/src/Put.ts @@ -1,19 +1,36 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "../deps.ts"; +import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; +type MethodDecorator = ( + // deno-lint-ignore ban-types + arg1: Function | object, + arg2: ClassMethodDecoratorContext | string, +) => void; + /** * Decorator that should be used on the Controller Class Method - * for PUT endpoints + * for `PUT` endpoints + * @example + * ```ts + * import { Controller, Put } from "@dklab/oak-routing-ctrl" + * + * ;@Controller() + * class ExampleClass { + * ;@Put("/") + * async updateSomething() { + * // implementation + * } + * } + * ``` */ export const Put = ( path: string = "", openApiSpec?: OakOpenApiSpec, -) => -// deno-lint-ignore ban-types -(arg1: Function | object, arg2: ClassMethodDecoratorContext | string): void => { +): MethodDecorator => +(arg1, arg2): void => { const fnName: string = getUserSuppliedDecoratedMethodName(arg1, arg2); debug( `invoking Put MethodDecorator for ${fnName} with pathPrefix ${path} -`, diff --git a/src/Put_test.ts b/src/Put_test.ts index 4a4972f..5a82f5b 100644 --- a/src/Put_test.ts +++ b/src/Put_test.ts @@ -1,11 +1,10 @@ +import { assertEquals, assertInstanceOf } from "@std/assert"; import { - assertEquals, - assertInstanceOf, assertSpyCall, assertSpyCalls, type MethodSpy, spy, -} from "../dev_deps.ts"; +} from "@std/testing/mock"; import { store } from "./Store.ts"; import { _internal } from "./Put.ts"; diff --git a/src/Store_test.ts b/src/Store_test.ts index 4a62589..4a32646 100644 --- a/src/Store_test.ts +++ b/src/Store_test.ts @@ -1,9 +1,5 @@ -import { - assertEquals, - assertSpyCall, - assertSpyCalls, - spy, -} from "../dev_deps.ts"; +import { assertEquals } from "@std/assert"; +import { assertSpyCall, assertSpyCalls, spy } from "@std/testing/mock"; import { register, store } from "./Store.ts"; Deno.test("Store", () => { diff --git a/src/oasStore.ts b/src/oasStore.ts index 2feacdb..514ac30 100644 --- a/src/oasStore.ts +++ b/src/oasStore.ts @@ -1,4 +1,5 @@ -import { type OakOpenApiSpec, type RouteConfig } from "../deps.ts"; +import { type RouteConfig } from "@asteasolutions/zod-to-openapi"; +import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; import { SupportedVerb } from "./Store.ts"; import { debug } from "./utils/logger.ts"; diff --git a/src/oasStore_test.ts b/src/oasStore_test.ts index f8aeb02..c612e1c 100644 --- a/src/oasStore_test.ts +++ b/src/oasStore_test.ts @@ -1,5 +1,6 @@ -import { z } from "../deps.ts"; -import { assertEquals, assertInstanceOf, ZodObject } from "../dev_deps.ts"; +import { z } from "./utils/schema_utils.ts"; +import { assertEquals, assertInstanceOf } from "@std/assert"; +import { ZodObject } from "zod"; import { oasStore, patchOasPath, updateOas } from "./oasStore.ts"; import { _internal } from "./oasStore.ts"; diff --git a/src/useOakServer.ts b/src/useOakServer.ts index 7834106..d267949 100644 --- a/src/useOakServer.ts +++ b/src/useOakServer.ts @@ -1,5 +1,6 @@ import { debug } from "./utils/logger.ts"; -import { type Application, Router, Status, z } from "../deps.ts"; +import { type Application, Router, Status } from "@oak/oak"; +import { z } from "./utils/schema_utils.ts"; import type { ControllerClass } from "./Controller.ts"; import { store } from "./Store.ts"; @@ -52,4 +53,9 @@ export const useOakServer = ( app.use(oakRouter.allowedMethods()); }; +/** + * alias of {@linkcode useOakServer} + */ +export const useOak = useOakServer; + export const _internal = { oakRouter }; diff --git a/src/useOakServer_test.ts b/src/useOakServer_test.ts index 2545242..ed05a93 100644 --- a/src/useOakServer_test.ts +++ b/src/useOakServer_test.ts @@ -4,16 +4,12 @@ import { type ErrorStatus, RouteContext, Status, - z, -} from "../deps.ts"; -import { - assertEquals, - assertSnapshot, - assertSpyCallArg, - assertSpyCalls, - oakTesting, - spy, -} from "../dev_deps.ts"; + testing as oakTesting, +} from "@oak/oak"; +import { z } from "./utils/schema_utils.ts"; +import { assertEquals } from "@std/assert"; +import { assertSpyCallArg, assertSpyCalls, spy } from "@std/testing/mock"; +import { assertSnapshot } from "@std/testing/snapshot"; import { Controller, type ControllerMethodArg, diff --git a/src/useOas.ts b/src/useOas.ts index 60dc67d..b614231 100644 --- a/src/useOas.ts +++ b/src/useOas.ts @@ -1,11 +1,11 @@ -import { Application } from "../deps.ts"; +import { Application } from "@oak/oak"; import { oasStore } from "./oasStore.ts"; import { OpenApiGeneratorV3, - type OpenAPIObjectConfig, OpenAPIRegistry, type RouteConfig, -} from "../deps.ts"; +} from "@asteasolutions/zod-to-openapi"; +import { type OpenAPIObjectConfig } from "npm:@asteasolutions/zod-to-openapi@^7.2.0/dist/v3.0/openapi-generator"; import { debug } from "./utils/logger.ts"; import { inspect } from "./utils/inspect.ts"; @@ -26,7 +26,11 @@ const defaultOasUiTemplate = ` const registry = new OpenAPIRegistry(); -type UseOasConfig = Partial & { +/** + * interface for an object used to configure how the Open API Spec + * is generated (e.g. `/oas.json`) + */ +export type UseOasConfig = Partial & { jsonPath?: string; uiPath?: string; uiTemplate?: string; @@ -85,9 +89,9 @@ const _useOas: UseOas = ( /** * helper method to enable Open API Spec for the routes * declared with oak-routing-ctrl decorators - * @param app the oak Application instance - * @param cfg optional configuration object to - * finetune the OAS spec documentation + * @param {Application} app the {@linkcode Application} instance from `@oak/oak` + * @param {UseOasConfig} [cfg] optional configuration object to + * finetune the Open API spec documentation */ export const useOas = ( app: Application, diff --git a/src/useOas_test.ts b/src/useOas_test.ts index 4bfd90e..d9d6cdf 100644 --- a/src/useOas_test.ts +++ b/src/useOas_test.ts @@ -1,14 +1,9 @@ -import { - assertEquals, - assertSnapshot, - assertSpyCall, - assertSpyCalls, - type Middleware, - oakTesting, - spy, - stub, -} from "../dev_deps.ts"; -import { OpenApiGeneratorV3, z } from "../deps.ts"; +import { type Middleware, testing as oakTesting } from "@oak/oak"; +import { assertEquals } from "@std/assert"; +import { assertSpyCall, assertSpyCalls, spy, stub } from "@std/testing/mock"; +import { assertSnapshot } from "@std/testing/snapshot"; +import { OpenApiGeneratorV3 } from "@asteasolutions/zod-to-openapi"; +import { z } from "./utils/schema_utils.ts"; import { oasStore, updateOas } from "./oasStore.ts"; import { _internal, useOas } from "./useOas.ts"; import { mockRequestInternals } from "../test_utils/mockRequestInternals.ts"; diff --git a/src/utils/getUserSuppliedDecoratedMethodName_test.ts b/src/utils/getUserSuppliedDecoratedMethodName_test.ts index 1b1666e..3d535d7 100644 --- a/src/utils/getUserSuppliedDecoratedMethodName_test.ts +++ b/src/utils/getUserSuppliedDecoratedMethodName_test.ts @@ -1,4 +1,4 @@ -import { assertEquals, assertThrows } from "../../dev_deps.ts"; +import { assertEquals, assertThrows } from "@std/assert"; import { ERR_UNSUPPORTED_CLASS_METHOD_DECORATOR_RUNTIME_BEHAVIOR } from "../Constants.ts"; import { getUserSuppliedDecoratedMethodName } from "./getUserSuppliedDecoratedMethodName.ts"; diff --git a/src/utils/inspect_test.ts b/src/utils/inspect_test.ts index d51567f..7f0c7c6 100644 --- a/src/utils/inspect_test.ts +++ b/src/utils/inspect_test.ts @@ -1,4 +1,4 @@ -import { assertSnapshot } from "../../dev_deps.ts"; +import { assertSnapshot } from "@std/testing/snapshot"; import { inspect } from "./inspect.ts"; const testObj = { diff --git a/src/utils/logger_test.ts b/src/utils/logger_test.ts index a8b2fa1..08fef12 100644 --- a/src/utils/logger_test.ts +++ b/src/utils/logger_test.ts @@ -1,14 +1,11 @@ import { debug } from "./logger.ts"; +import { afterEach, beforeEach, describe, it } from "@std/testing/bdd"; import { - afterEach, assertSpyCall, assertSpyCalls, - beforeEach, - describe, - it, type Stub, stub, -} from "../../dev_deps.ts"; +} from "@std/testing/mock"; let stubConsoleDebug: Stub; @@ -66,6 +63,6 @@ function stubGetEnv(envName: string, stubValue: string | undefined): Stub { return stub( Deno.env, "get", - (key) => key === envName ? stubValue : Deno.env.get(key), + (key: string) => key === envName ? stubValue : Deno.env.get(key), ); } diff --git a/deps.ts b/src/utils/schema_utils.ts similarity index 79% rename from deps.ts rename to src/utils/schema_utils.ts index a5e5166..b84135e 100644 --- a/deps.ts +++ b/src/utils/schema_utils.ts @@ -1,21 +1,32 @@ -export { join } from "jsr:@std/path@^1.0.8"; - -export { Router, Status } from "jsr:@oak/oak@^17.1.3"; - -export type { - Application, - Context, - ErrorStatus, - Next, - RouteContext, -} from "jsr:@oak/oak@^17.1.3"; - import { extendZodWithOpenApi, type ResponseConfig, type RouteConfig, } from "npm:@asteasolutions/zod-to-openapi@^7.2.0"; +/** + * Open API Schema interface, usable when composing the request/response + * schema for a REST endpoint (declared when using the + * decorators such as {@linkcode Get}, {@linkcode Post}, etc.) + * @example + * ```ts + * import { Get } from "@dklab/oak-routing-ctrl" + * + * const GetItemsSchema: OakOpenApiSpec = { + * responses: { + * "200": { "description": "OK" } + * } + * } + * + * // later inside the Controller Class + * class ExampleClass { + * ;@Get("/", GetItemsSchema) + * async getSomething() { + * // + * } + * } + * ``` + */ export type OakOpenApiSpec = & Omit & { @@ -24,16 +35,6 @@ export type OakOpenApiSpec = }; }; -export { type ResponseConfig, type RouteConfig }; - -export { - OpenApiGeneratorV3, - OpenAPIRegistry, - type ZodRequestBody, -} from "npm:@asteasolutions/zod-to-openapi@^7.2.0"; - -export { type OpenAPIObjectConfig } from "npm:@asteasolutions/zod-to-openapi@^7.2.0/dist/v3.0/openapi-generator"; - // must import from `npm:` instead of from `deno.land` to be compatible with `@asteasolutions/zod-to-openapi` import { z as slowTypedZ } from "npm:zod@^3.23.8"; extendZodWithOpenApi(slowTypedZ); diff --git a/test_utils/mockRequestInternals.ts b/test_utils/mockRequestInternals.ts index de63ba3..e4f1cd8 100644 --- a/test_utils/mockRequestInternals.ts +++ b/test_utils/mockRequestInternals.ts @@ -1,4 +1,4 @@ -import { type BodyType, type Request } from "../dev_deps.ts"; +import { type BodyType, type Request } from "@oak/oak"; export type MockRequestBodyDefinition = { type: BodyType; From f6d1311cdeebb6238048e6dab9e39c1d78ca3cc0 Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Sat, 7 Dec 2024 03:28:27 +0100 Subject: [PATCH 02/14] preferring jsonc --- deno.json => deno.jsonc | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename deno.json => deno.jsonc (100%) diff --git a/deno.json b/deno.jsonc similarity index 100% rename from deno.json rename to deno.jsonc From 6a9f3d29b63580b00106c9a900ef52eb641aa597 Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Sat, 7 Dec 2024 03:31:44 +0100 Subject: [PATCH 03/14] consolidated exports --- mod.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mod.ts b/mod.ts index 078ffb7..cd43c36 100644 --- a/mod.ts +++ b/mod.ts @@ -1,5 +1,4 @@ -export { useOakServer } from "./src/useOakServer.ts"; -export { useOak } from "./src/useOakServer.ts"; +export { useOak, useOakServer } from "./src/useOakServer.ts"; export { useOas, type UseOasConfig } from "./src/useOas.ts"; export { Controller } from "./src/Controller.ts"; export { From adaa0e0edb28bb44620cfe79c81c2ae8f9ef1bca Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Sat, 7 Dec 2024 03:40:52 +0100 Subject: [PATCH 04/14] removed deprecated code --- src/ControllerMethodArgs_test.ts | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/ControllerMethodArgs_test.ts b/src/ControllerMethodArgs_test.ts index bba4517..e2e54c8 100644 --- a/src/ControllerMethodArgs_test.ts +++ b/src/ControllerMethodArgs_test.ts @@ -1,25 +1,7 @@ import { type BodyType, testing as oakTesting } from "@oak/oak"; import { Body } from "@oak/oak/body"; -import { - assertEquals, - // assertSpyCalls, - assertStringIncludes, - assertThrows, - // Body, - // type BodyType, - // Buffer, - // oakTesting, - // spy, -} from "@std/assert"; -import { - // assertEquals, - assertSpyCalls, - // assertStringIncludes, - // assertThrows, - // Body, - // type BodyType, - spy, -} from "@std/testing/mock"; +import { assertEquals, assertStringIncludes, assertThrows } from "@std/assert"; +import { assertSpyCalls, spy } from "@std/testing/mock"; import { Buffer } from "@std/io"; import { ERR_UNSUPPORTED_CLASS_METHOD_DECORATOR_RUNTIME_BEHAVIOR } from "./Constants.ts"; import { From 89e22848949a443fd93f92eddc8e957a0fba3dac Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Sun, 15 Dec 2024 18:44:24 +0100 Subject: [PATCH 05/14] added tests, pruned dependencies, updated proj config --- .vscode/settings.json | 3 +- CHANGELOG.md | 11 ++++- deno.jsonc | 10 ++++- deno.lock | 48 +++------------------ src/ControllerMethodArgs.ts | 6 ++- src/ControllerMethodArgs_test.ts | 38 ++++++++++++++++ src/__snapshots__/useOakServer_test.ts.snap | 20 +++++++++ src/useOakServer_test.ts | 11 +++++ src/useOas.ts | 2 +- src/utils/schema_utils.ts | 4 +- 10 files changed, 102 insertions(+), 51 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index d40f5ad..e883e40 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,6 @@ "editor.tabSize": 2, "deno.enable": true, "editor.formatOnSave": true, - "editor.defaultFormatter": "denoland.vscode-deno" + "editor.defaultFormatter": "denoland.vscode-deno", + "[typescript]": { "editor.defaultFormatter": "denoland.vscode-deno" } } diff --git a/CHANGELOG.md b/CHANGELOG.md index ef9ea60..dbd9b46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,17 @@ ## Unreleased +### Added + +- Laxer usage of `ControllerMethodArgs` decorator: now allowing `queries`, + `params`, `header` as literal arguments, so that things still work even if + users accidentally / deliberately use the undocumented singular / plural forms + ### Changed - switched from `deps.ts` and `dev_deps.ts` to `deno.jsonc` -- revamped documentation -- code format +- revamped documentation (JSDoc) +- code format & code format settings for VS Code users +- upgraded dependencies (`zod@^3.24.1`) ## [0.12.2] - 2024-12-06 diff --git a/deno.jsonc b/deno.jsonc index 4b24d57..8bac8bb 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,18 +1,24 @@ { "imports": { "@asteasolutions/zod-to-openapi": "npm:@asteasolutions/zod-to-openapi@^7.3.0", - "@dklab/oak-routing-ctrl": "jsr:@dklab/oak-routing-ctrl@^0.12.2", "@oak/oak": "jsr:@oak/oak@^17.1.3", "@std/assert": "jsr:@std/assert@^1.0.9", "@std/io": "jsr:@std/io@^0.225.0", "@std/path": "jsr:@std/path@^1.0.8", "@std/testing": "jsr:@std/testing@^1.0.6", - "zod": "npm:zod@^3.23.8" + "zod": "npm:zod@^3.24.1" }, "tasks": { "pretty": "deno lint --ignore=docs && deno check . && deno fmt", "test": "deno test -RE", "check-doc": "deno check --doc .", "doc": "deno doc --html mod.ts" + }, + "fmt": { + "useTabs": false, + "indentWidth": 2, + "semiColons": true, + "singleQuote": false, + "proseWrap": "always" } } diff --git a/deno.lock b/deno.lock index f456297..cb63557 100644 --- a/deno.lock +++ b/deno.lock @@ -1,16 +1,13 @@ { "version": "4", "specifiers": { - "jsr:@dklab/oak-routing-ctrl@~0.12.2": "0.12.2", "jsr:@oak/commons@1": "1.0.0", "jsr:@oak/oak@^17.1.3": "17.1.3", "jsr:@std/assert@1": "1.0.9", - "jsr:@std/assert@^1.0.7": "1.0.9", "jsr:@std/assert@^1.0.9": "1.0.9", "jsr:@std/bytes@1": "1.0.4", "jsr:@std/bytes@^1.0.2": "1.0.4", "jsr:@std/crypto@1": "1.0.3", - "jsr:@std/data-structures@^1.0.4": "1.0.4", "jsr:@std/encoding@1": "1.0.5", "jsr:@std/encoding@^1.0.5": "1.0.5", "jsr:@std/fs@^1.0.6": "1.0.6", @@ -21,24 +18,12 @@ "jsr:@std/media-types@1": "1.1.0", "jsr:@std/path@1": "1.0.8", "jsr:@std/path@^1.0.8": "1.0.8", - "jsr:@std/testing@^1.0.4": "1.0.6", "jsr:@std/testing@^1.0.6": "1.0.6", - "npm:@asteasolutions/zod-to-openapi@^7.2.0": "7.2.0_zod@3.23.8", - "npm:@asteasolutions/zod-to-openapi@^7.3.0": "7.3.0_zod@3.23.8", - "npm:@types/node@*": "22.5.4", + "npm:@asteasolutions/zod-to-openapi@^7.3.0": "7.3.0_zod@3.24.1", "npm:path-to-regexp@6.2.1": "6.2.1", - "npm:zod@^3.23.8": "3.23.8" + "npm:zod@^3.24.1": "3.24.1" }, "jsr": { - "@dklab/oak-routing-ctrl@0.12.2": { - "integrity": "ffafb942871916d2aeb685403069dc2155fa2dc070b41235aa39ad6074ee617b", - "dependencies": [ - "jsr:@oak/oak", - "jsr:@std/path@^1.0.8", - "npm:@asteasolutions/zod-to-openapi@^7.2.0", - "npm:zod" - ] - }, "@oak/commons@1.0.0": { "integrity": "49805b55603c3627a9d6235c0655aa2b6222d3036b3a13ff0380c16368f607ac", "dependencies": [ @@ -76,9 +61,6 @@ "@std/crypto@1.0.3": { "integrity": "a2a32f51ddef632d299e3879cd027c630dcd4d1d9a5285d6e6788072f4e51e7f" }, - "@std/data-structures@1.0.4": { - "integrity": "fa0e20c11eb9ba673417450915c750a0001405a784e2a4e0c3725031681684a0" - }, "@std/encoding@1.0.5": { "integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04" }, @@ -119,7 +101,6 @@ "integrity": "9192ded2d34065f4c959fdc1921fe836770abb9194410c2cc8a0fff4eff5c893", "dependencies": [ "jsr:@std/assert@^1.0.9", - "jsr:@std/data-structures", "jsr:@std/fs", "jsr:@std/internal", "jsr:@std/path@^1.0.8" @@ -127,26 +108,13 @@ } }, "npm": { - "@asteasolutions/zod-to-openapi@7.2.0_zod@3.23.8": { - "integrity": "sha512-Va+Fq1QzKkSgmiYINSp3cASFhMsbdRH/kmCk2feijhC+yNjGoC056CRqihrVFhR8MY8HOZHdlYm2Ns2lmszCiw==", - "dependencies": [ - "openapi3-ts", - "zod" - ] - }, - "@asteasolutions/zod-to-openapi@7.3.0_zod@3.23.8": { + "@asteasolutions/zod-to-openapi@7.3.0_zod@3.24.1": { "integrity": "sha512-7tE/r1gXwMIvGnXVUdIqUhCU1RevEFC4Jk6Bussa0fk1ecbnnINkZzj1EOAJyE/M3AI25DnHT/zKQL1/FPFi8Q==", "dependencies": [ "openapi3-ts", "zod" ] }, - "@types/node@22.5.4": { - "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", - "dependencies": [ - "undici-types" - ] - }, "openapi3-ts@4.4.0": { "integrity": "sha512-9asTNB9IkKEzWMcHmVZE7Ts3kC9G7AFHfs8i7caD8HbI76gEjdkId4z/AkP83xdZsH7PLAnnbl47qZkXuxpArw==", "dependencies": [ @@ -156,26 +124,22 @@ "path-to-regexp@6.2.1": { "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" }, - "undici-types@6.19.8": { - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" - }, "yaml@2.6.1": { "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==" }, - "zod@3.23.8": { - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==" + "zod@3.24.1": { + "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==" } }, "workspace": { "dependencies": [ - "jsr:@dklab/oak-routing-ctrl@~0.12.2", "jsr:@oak/oak@^17.1.3", "jsr:@std/assert@^1.0.9", "jsr:@std/io@0.225", "jsr:@std/path@^1.0.8", "jsr:@std/testing@^1.0.6", "npm:@asteasolutions/zod-to-openapi@^7.3.0", - "npm:zod@^3.23.8" + "npm:zod@^3.24.1" ] } } diff --git a/src/ControllerMethodArgs.ts b/src/ControllerMethodArgs.ts index ab28b19..ddf6fef 100644 --- a/src/ControllerMethodArgs.ts +++ b/src/ControllerMethodArgs.ts @@ -180,6 +180,7 @@ function getEnhancedHandler( for (const p of consumerDesirableParams) { switch (true) { case p === "param": + case p === "params" as ControllerMethodArg: // undocumented on purpose // path param decoratedArgs.push(ctx.params); break; @@ -188,10 +189,13 @@ function getEnhancedHandler( decoratedArgs.push(parsedReqBody); break; case p === "query": + case p === "queries" as ControllerMethodArg: // undocumented on purpose // search query a.k.a URLSearchParams decoratedArgs.push(parsedReqSearchParams); break; - case p === "headers": { + case p === "headers": + case p === "header" as ControllerMethodArg: // undocumented on purpose + { // request headers const headers: Record = {}; ctx.request.headers.forEach((v: string, k: string) => headers[k] = v); diff --git a/src/ControllerMethodArgs_test.ts b/src/ControllerMethodArgs_test.ts index e2e54c8..9d4d8f5 100644 --- a/src/ControllerMethodArgs_test.ts +++ b/src/ControllerMethodArgs_test.ts @@ -887,6 +887,44 @@ Deno.test("getEnhancedHandler - not declaring any param", async () => { assertSpyCalls(testHandler, 1); }); +Deno.test("getEnhancedHandler - declaring undocumented params", async () => { + const spyParseOakRequestBody = spy(_internal, "parseOakReqBody"); + // deno-lint-ignore no-explicit-any + const testHandler = spy((..._rest: any[]) => 44); + // deno-lint-ignore ban-types + const enhancedHandler: Function = _internal.getEnhancedHandler( + testHandler, + "context" as ControllerMethodArg, + "params" as ControllerMethodArg, + "queries" as ControllerMethodArg, + "header" as ControllerMethodArg, + "hiddenFeature" as ControllerMethodArg, + ); + const ctx = createMockContext({ + path: "/hello/world", + params: { lorem: "undocumented usage", hiddenFeature: "84" }, + headers: [["X-Foo", "Bearer Bar"]], + }); + Object.defineProperty(ctx.request, "body", { + get: () => createMockRequestBody("binary"), + }); + Object.defineProperty(ctx.request.url, "searchParams", { + value: new Map([["ipsum", "dolor"]]), + }); + await enhancedHandler(ctx); + const [context, param, query, headers, hiddenFeature] = + testHandler.calls[0].args; + assertEquals(param, { lorem: "undocumented usage", hiddenFeature: "84" }); + assertEquals(query, { ipsum: "dolor" }); + assertEquals(hiddenFeature, "84"); + assertEquals(context, ctx); + assertEquals(headers, { "x-foo": "Bearer Bar" }); + assertEquals(testHandler.calls[0].returned, 44); + assertSpyCalls(testHandler, 1); + assertSpyCalls(spyParseOakRequestBody, 1); + spyParseOakRequestBody.restore(); +}); + /** * @NOTE if/when `oak` supports such a method, better import from there instead */ diff --git a/src/__snapshots__/useOakServer_test.ts.snap b/src/__snapshots__/useOakServer_test.ts.snap index 2e4a738..8c1d08a 100644 --- a/src/__snapshots__/useOakServer_test.ts.snap +++ b/src/__snapshots__/useOakServer_test.ts.snap @@ -57,6 +57,26 @@ snapshot[`useOakServer - fully decorated Controller 1`] = ` path: "/test/baz/:zaz", regexp: /^\\/test\\/baz(?:\\/([^\\/#\\?]+?))[\\/#\\?]?\$/i, }, + { + methods: [ + "HEAD", + "GET", + ], + middleware: [ + [AsyncFunction (anonymous)], + ], + options: { + end: undefined, + ignoreCaptures: undefined, + sensitive: undefined, + strict: undefined, + }, + paramNames: [ + "zaz_zaz", + ], + path: "/test/dolor/:zaz_zaz", + regexp: /^\\/test\\/dolor(?:\\/([^\\/#\\?]+?))[\\/#\\?]?\$/i, + }, { methods: [ "PUT", diff --git a/src/useOakServer_test.ts b/src/useOakServer_test.ts index ed05a93..f90c12d 100644 --- a/src/useOakServer_test.ts +++ b/src/useOakServer_test.ts @@ -66,6 +66,11 @@ class TestController { baz(query: Record, param: Record) { return `hello, path /baz/${param.zaz} with query ${query.someKey}`; } + @Get("/dolor/:zaz_zaz") + @ControllerMethodArgs("params" as ControllerMethodArg) // intentional coercing to test undocumented usage + dolor(param: Record) { + return `hello, path /dolor/${param.zaz_zaz}`; + } @Put("/taz/:someId") @ControllerMethodArgs("body") taz(body: ArrayBuffer, ctx: RouteContext<"/taz/:someId">) { @@ -188,6 +193,12 @@ Deno.test({ mockRequestPathParams: { zaz: "jaz" }, expectedResponse: "hello, path /baz/jaz with query chaz", }, + { + caseDescription: "handler with 'params' as undocumented usage", + method: "get", + mockRequestPathParams: { zaz_zaz: "jaz_jaz" }, + expectedResponse: "hello, path /dolor/jaz_jaz", + }, { caseDescription: "handler for a request with a binary payload", method: "put", diff --git a/src/useOas.ts b/src/useOas.ts index b614231..16d4c21 100644 --- a/src/useOas.ts +++ b/src/useOas.ts @@ -5,7 +5,7 @@ import { OpenAPIRegistry, type RouteConfig, } from "@asteasolutions/zod-to-openapi"; -import { type OpenAPIObjectConfig } from "npm:@asteasolutions/zod-to-openapi@^7.2.0/dist/v3.0/openapi-generator"; +import { type OpenAPIObjectConfig } from "@asteasolutions/zod-to-openapi/dist/v3.0/openapi-generator"; import { debug } from "./utils/logger.ts"; import { inspect } from "./utils/inspect.ts"; diff --git a/src/utils/schema_utils.ts b/src/utils/schema_utils.ts index b84135e..6b40f87 100644 --- a/src/utils/schema_utils.ts +++ b/src/utils/schema_utils.ts @@ -2,7 +2,7 @@ import { extendZodWithOpenApi, type ResponseConfig, type RouteConfig, -} from "npm:@asteasolutions/zod-to-openapi@^7.2.0"; +} from "@asteasolutions/zod-to-openapi"; /** * Open API Schema interface, usable when composing the request/response @@ -36,7 +36,7 @@ export type OakOpenApiSpec = }; // must import from `npm:` instead of from `deno.land` to be compatible with `@asteasolutions/zod-to-openapi` -import { z as slowTypedZ } from "npm:zod@^3.23.8"; +import { z as slowTypedZ } from "zod"; extendZodWithOpenApi(slowTypedZ); type SubsetOfZ = Pick< typeof slowTypedZ, From 796e9530b82e2ebfa384dcb8ce818f23e266ba36 Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Sun, 15 Dec 2024 19:24:45 +0100 Subject: [PATCH 06/14] v0.13.0-alpha.1 - see CHANGELOG for details --- jsr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsr.json b/jsr.json index 868a522..51b1c50 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@dklab/oak-routing-ctrl", - "version": "0.13.0", + "version": "0.13.0-alpha.1", "exports": { ".": "./mod.ts", "./mod": "./mod.ts" From 38e4778ea298fae1253d6a15a22c9db0e67ed23b Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Sun, 15 Dec 2024 19:35:11 +0100 Subject: [PATCH 07/14] fixed proj meta for lib publishing --- CHANGELOG.md | 4 ++++ deno.jsonc | 33 ++++++++++++++++++++++++++------- jsr.json | 21 --------------------- 3 files changed, 30 insertions(+), 28 deletions(-) delete mode 100644 jsr.json diff --git a/CHANGELOG.md b/CHANGELOG.md index dbd9b46..18e53dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ - code format & code format settings for VS Code users - upgraded dependencies (`zod@^3.24.1`) +## Removed + +- the file `jsr.json` is removed in favour of file `deno.jsonc` + ## [0.12.2] - 2024-12-06 ### Added diff --git a/deno.jsonc b/deno.jsonc index 8bac8bb..14a5fe9 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,4 +1,16 @@ { + "name": "@dklab/oak-routing-ctrl", + "version": "0.13.0-alpha.1", + "exports": { + ".": "./mod.ts", + "./mod": "./mod.ts" + }, + "tasks": { + "pretty": "deno lint --ignore=docs && deno check . && deno fmt", + "test": "deno test -RE", + "check-doc": "deno check --doc .", + "doc": "deno doc --html mod.ts" + }, "imports": { "@asteasolutions/zod-to-openapi": "npm:@asteasolutions/zod-to-openapi@^7.3.0", "@oak/oak": "jsr:@oak/oak@^17.1.3", @@ -8,17 +20,24 @@ "@std/testing": "jsr:@std/testing@^1.0.6", "zod": "npm:zod@^3.24.1" }, - "tasks": { - "pretty": "deno lint --ignore=docs && deno check . && deno fmt", - "test": "deno test -RE", - "check-doc": "deno check --doc .", - "doc": "deno doc --html mod.ts" - }, "fmt": { "useTabs": false, "indentWidth": 2, "semiColons": true, "singleQuote": false, "proseWrap": "always" - } + }, + "exclude": [ + "./docs", + "./test_utils", + "**/*_test.ts", + "cov_profile", + "cov_profile.lcov", + "dev_deps.ts", + "**/__snapshots__", + ".github", + ".vscode", + "./CONTRIBUTING.md", + "./GOVERNANCE.md" + ] } diff --git a/jsr.json b/jsr.json deleted file mode 100644 index 51b1c50..0000000 --- a/jsr.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "@dklab/oak-routing-ctrl", - "version": "0.13.0-alpha.1", - "exports": { - ".": "./mod.ts", - "./mod": "./mod.ts" - }, - "exclude": [ - "./docs", - "./test_utils", - "**/*_test.ts", - "cov_profile", - "cov_profile.lcov", - "dev_deps.ts", - "**/__snapshots__", - ".github", - ".vscode", - "./CONTRIBUTING.md", - "./GOVERNANCE.md" - ] -} From 36196faecad0d124d1aca58c8c66a2e1c4201331 Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Sun, 15 Dec 2024 19:38:32 +0100 Subject: [PATCH 08/14] updated ts import flavour --- src/ControllerMethodArgs.ts | 2 +- src/Delete.ts | 2 +- src/Get.ts | 2 +- src/Head.ts | 2 +- src/Options.ts | 2 +- src/Patch.ts | 2 +- src/Post.ts | 2 +- src/Put.ts | 2 +- src/oasStore.ts | 6 +++--- src/useOas.ts | 4 ++-- 10 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ControllerMethodArgs.ts b/src/ControllerMethodArgs.ts index ddf6fef..90fd90a 100644 --- a/src/ControllerMethodArgs.ts +++ b/src/ControllerMethodArgs.ts @@ -1,5 +1,5 @@ import { debug } from "./utils/logger.ts"; -import { type Context, type RouteContext } from "@oak/oak"; +import type { Context, RouteContext } from "@oak/oak"; import { ERR_UNSUPPORTED_CLASS_METHOD_DECORATOR_RUNTIME_BEHAVIOR } from "./Constants.ts"; /** diff --git a/src/Delete.ts b/src/Delete.ts index 039885a..0ef772d 100644 --- a/src/Delete.ts +++ b/src/Delete.ts @@ -1,7 +1,7 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; +import type { OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; type MethodDecorator = ( diff --git a/src/Get.ts b/src/Get.ts index 2e642d2..9fb8d7d 100644 --- a/src/Get.ts +++ b/src/Get.ts @@ -1,7 +1,7 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; +import type { OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; type MethodDecorator = ( diff --git a/src/Head.ts b/src/Head.ts index b2942df..2609970 100644 --- a/src/Head.ts +++ b/src/Head.ts @@ -1,7 +1,7 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; +import type { OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; type MethodDecorator = ( diff --git a/src/Options.ts b/src/Options.ts index 2f578a1..6bf2b8e 100644 --- a/src/Options.ts +++ b/src/Options.ts @@ -1,7 +1,7 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; +import type { OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; type MethodDecorator = ( diff --git a/src/Patch.ts b/src/Patch.ts index 9506a65..cd225c4 100644 --- a/src/Patch.ts +++ b/src/Patch.ts @@ -1,7 +1,7 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; +import type { OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; type MethodDecorator = ( diff --git a/src/Post.ts b/src/Post.ts index f2f1c41..97a40bc 100644 --- a/src/Post.ts +++ b/src/Post.ts @@ -1,7 +1,7 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; +import type { OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; type MethodDecorator = ( diff --git a/src/Put.ts b/src/Put.ts index 09ab053..4bc5d9d 100644 --- a/src/Put.ts +++ b/src/Put.ts @@ -1,7 +1,7 @@ import { debug } from "./utils/logger.ts"; import { register } from "./Store.ts"; import { getUserSuppliedDecoratedMethodName } from "./utils/getUserSuppliedDecoratedMethodName.ts"; -import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; +import type { OakOpenApiSpec } from "./utils/schema_utils.ts"; import { updateOas } from "./oasStore.ts"; type MethodDecorator = ( diff --git a/src/oasStore.ts b/src/oasStore.ts index 514ac30..369fef1 100644 --- a/src/oasStore.ts +++ b/src/oasStore.ts @@ -1,6 +1,6 @@ -import { type RouteConfig } from "@asteasolutions/zod-to-openapi"; -import { type OakOpenApiSpec } from "./utils/schema_utils.ts"; -import { SupportedVerb } from "./Store.ts"; +import type { RouteConfig } from "@asteasolutions/zod-to-openapi"; +import type { OakOpenApiSpec } from "./utils/schema_utils.ts"; +import type { SupportedVerb } from "./Store.ts"; import { debug } from "./utils/logger.ts"; // fnName|method|path => OasRouteConfig diff --git a/src/useOas.ts b/src/useOas.ts index 16d4c21..2c887d5 100644 --- a/src/useOas.ts +++ b/src/useOas.ts @@ -1,11 +1,11 @@ -import { Application } from "@oak/oak"; +import type { Application } from "@oak/oak"; import { oasStore } from "./oasStore.ts"; import { OpenApiGeneratorV3, OpenAPIRegistry, type RouteConfig, } from "@asteasolutions/zod-to-openapi"; -import { type OpenAPIObjectConfig } from "@asteasolutions/zod-to-openapi/dist/v3.0/openapi-generator"; +import type { OpenAPIObjectConfig } from "@asteasolutions/zod-to-openapi/dist/v3.0/openapi-generator"; import { debug } from "./utils/logger.ts"; import { inspect } from "./utils/inspect.ts"; From 00b2ba8011816794a580331b6a476a8c2c1a3ef6 Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Sun, 15 Dec 2024 19:43:29 +0100 Subject: [PATCH 09/14] updated meta config --- deno.jsonc | 2 -- deno.lock | 10 ++++++++++ src/useOakServer_test.ts | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/deno.jsonc b/deno.jsonc index 14a5fe9..16b7247 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -30,10 +30,8 @@ "exclude": [ "./docs", "./test_utils", - "**/*_test.ts", "cov_profile", "cov_profile.lcov", - "dev_deps.ts", "**/__snapshots__", ".github", ".vscode", diff --git a/deno.lock b/deno.lock index cb63557..7415d2f 100644 --- a/deno.lock +++ b/deno.lock @@ -20,6 +20,7 @@ "jsr:@std/path@^1.0.8": "1.0.8", "jsr:@std/testing@^1.0.6": "1.0.6", "npm:@asteasolutions/zod-to-openapi@^7.3.0": "7.3.0_zod@3.24.1", + "npm:@types/node@*": "22.5.4", "npm:path-to-regexp@6.2.1": "6.2.1", "npm:zod@^3.24.1": "3.24.1" }, @@ -115,6 +116,12 @@ "zod" ] }, + "@types/node@22.5.4": { + "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "dependencies": [ + "undici-types" + ] + }, "openapi3-ts@4.4.0": { "integrity": "sha512-9asTNB9IkKEzWMcHmVZE7Ts3kC9G7AFHfs8i7caD8HbI76gEjdkId4z/AkP83xdZsH7PLAnnbl47qZkXuxpArw==", "dependencies": [ @@ -124,6 +131,9 @@ "path-to-regexp@6.2.1": { "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" }, + "undici-types@6.19.8": { + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + }, "yaml@2.6.1": { "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==" }, diff --git a/src/useOakServer_test.ts b/src/useOakServer_test.ts index f90c12d..394e174 100644 --- a/src/useOakServer_test.ts +++ b/src/useOakServer_test.ts @@ -2,7 +2,7 @@ import type { SupportedVerb } from "./Store.ts"; import { type Context, type ErrorStatus, - RouteContext, + type RouteContext, Status, testing as oakTesting, } from "@oak/oak"; From d93f3772e7fc2140fbb42657afcddbfed3d1e159 Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Sun, 15 Dec 2024 21:43:18 +0100 Subject: [PATCH 10/14] updated meta config --- .github/workflows/pr.yml | 3 +++ .github/workflows/publish.yml | 3 +++ deno.jsonc | 13 +++++++++---- test_utils/mockRequestInternals.ts | 2 +- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index a15427e..1238404 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -28,6 +28,9 @@ jobs: - name: Run linter run: deno lint + - name: Check doc + run: deno task check-doc + - name: Run tests run: | deno test -A --coverage=cov_profile diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 809f30e..a409dba 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -26,6 +26,9 @@ jobs: - name: Run linter run: deno lint --ignore=\*\*\/\*_test.ts + - name: Check doc + run: deno task check-doc + - name: Run tests run: deno test -A diff --git a/deno.jsonc b/deno.jsonc index 16b7247..8eaa372 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -5,6 +5,14 @@ ".": "./mod.ts", "./mod": "./mod.ts" }, + "publish": { + "exclude": [ + "./test_utils", + "**/*_test.ts", + "./CONTRIBUTING.md", + "./GOVERNANCE.md" + ] + }, "tasks": { "pretty": "deno lint --ignore=docs && deno check . && deno fmt", "test": "deno test -RE", @@ -29,13 +37,10 @@ }, "exclude": [ "./docs", - "./test_utils", "cov_profile", "cov_profile.lcov", "**/__snapshots__", ".github", - ".vscode", - "./CONTRIBUTING.md", - "./GOVERNANCE.md" + ".vscode" ] } diff --git a/test_utils/mockRequestInternals.ts b/test_utils/mockRequestInternals.ts index e4f1cd8..0715d7b 100644 --- a/test_utils/mockRequestInternals.ts +++ b/test_utils/mockRequestInternals.ts @@ -1,4 +1,4 @@ -import { type BodyType, type Request } from "@oak/oak"; +import type { BodyType, Request } from "@oak/oak"; export type MockRequestBodyDefinition = { type: BodyType; From 59e779be03defc8c95213cd5092095646af72ca9 Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Mon, 16 Dec 2024 00:38:29 +0100 Subject: [PATCH 11/14] updated exported typing for OakOpenApiSpec --- CHANGELOG.md | 4 +++- deno.jsonc | 2 +- src/utils/schema_utils.ts | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18e53dd..5083ca2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,10 +12,12 @@ - revamped documentation (JSDoc) - code format & code format settings for VS Code users - upgraded dependencies (`zod@^3.24.1`) +- updated typing for `OakOpenApiSpec` (added prop: `request`, untyped unproven + prop: `requestBody`) ## Removed -- the file `jsr.json` is removed in favour of file `deno.jsonc` +- the file `jsr.json` is removed in favour of the file `deno.jsonc` ## [0.12.2] - 2024-12-06 diff --git a/deno.jsonc b/deno.jsonc index 8eaa372..b520bfb 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,6 +1,6 @@ { "name": "@dklab/oak-routing-ctrl", - "version": "0.13.0-alpha.1", + "version": "0.13.0-alpha.2", "exports": { ".": "./mod.ts", "./mod": "./mod.ts" diff --git a/src/utils/schema_utils.ts b/src/utils/schema_utils.ts index 6b40f87..08a9712 100644 --- a/src/utils/schema_utils.ts +++ b/src/utils/schema_utils.ts @@ -28,8 +28,9 @@ import { * ``` */ export type OakOpenApiSpec = - & Omit + & Omit & { + request?: RouteConfig["request"]; responses?: { [statusCode: string]: ResponseConfig; }; From 97bd396258142dff74c8b15bc9a6c17e90055ba0 Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Fri, 27 Dec 2024 12:31:59 +0100 Subject: [PATCH 12/14] v0.13.0-rc.1 - see CHANGELOG for details --- CHANGELOG.md | 6 +- deno.jsonc | 6 +- deno.lock | 34 ++++----- src/__snapshots__/useOas_test.ts.snap | 64 +++++++++++++++- src/oasStore.ts | 8 +- src/useOas.ts | 12 ++- src/useOas_test.ts | 102 +++++++++++++++++++++++++- 7 files changed, 205 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5083ca2..6e8e903 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,13 +5,17 @@ - Laxer usage of `ControllerMethodArgs` decorator: now allowing `queries`, `params`, `header` as literal arguments, so that things still work even if users accidentally / deliberately use the undocumented singular / plural forms +- Support for Open API Spec v3.1 +- Support for `operationId` and `tags` in OAS path request declarations +- Support for top-level `tags` in OAS document ### Changed - switched from `deps.ts` and `dev_deps.ts` to `deno.jsonc` - revamped documentation (JSDoc) - code format & code format settings for VS Code users -- upgraded dependencies (`zod@^3.24.1`) +- upgraded dependencies (`zod@^3.24.1`, `@std/assert@^1.0.10`, + `@std/testing@^1.0.8`) - updated typing for `OakOpenApiSpec` (added prop: `request`, untyped unproven prop: `requestBody`) diff --git a/deno.jsonc b/deno.jsonc index b520bfb..3701d34 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,6 +1,6 @@ { "name": "@dklab/oak-routing-ctrl", - "version": "0.13.0-alpha.2", + "version": "0.13.0-rc.1", "exports": { ".": "./mod.ts", "./mod": "./mod.ts" @@ -22,10 +22,10 @@ "imports": { "@asteasolutions/zod-to-openapi": "npm:@asteasolutions/zod-to-openapi@^7.3.0", "@oak/oak": "jsr:@oak/oak@^17.1.3", - "@std/assert": "jsr:@std/assert@^1.0.9", + "@std/assert": "jsr:@std/assert@^1.0.10", "@std/io": "jsr:@std/io@^0.225.0", "@std/path": "jsr:@std/path@^1.0.8", - "@std/testing": "jsr:@std/testing@^1.0.6", + "@std/testing": "jsr:@std/testing@^1.0.8", "zod": "npm:zod@^3.24.1" }, "fmt": { diff --git a/deno.lock b/deno.lock index 7415d2f..ee9028c 100644 --- a/deno.lock +++ b/deno.lock @@ -3,14 +3,14 @@ "specifiers": { "jsr:@oak/commons@1": "1.0.0", "jsr:@oak/oak@^17.1.3": "17.1.3", - "jsr:@std/assert@1": "1.0.9", - "jsr:@std/assert@^1.0.9": "1.0.9", + "jsr:@std/assert@1": "1.0.10", + "jsr:@std/assert@^1.0.10": "1.0.10", "jsr:@std/bytes@1": "1.0.4", "jsr:@std/bytes@^1.0.2": "1.0.4", "jsr:@std/crypto@1": "1.0.3", - "jsr:@std/encoding@1": "1.0.5", - "jsr:@std/encoding@^1.0.5": "1.0.5", - "jsr:@std/fs@^1.0.6": "1.0.6", + "jsr:@std/encoding@1": "1.0.6", + "jsr:@std/encoding@^1.0.5": "1.0.6", + "jsr:@std/fs@^1.0.8": "1.0.8", "jsr:@std/http@1": "1.0.12", "jsr:@std/internal@^1.0.5": "1.0.5", "jsr:@std/io@0.224": "0.224.9", @@ -18,7 +18,7 @@ "jsr:@std/media-types@1": "1.1.0", "jsr:@std/path@1": "1.0.8", "jsr:@std/path@^1.0.8": "1.0.8", - "jsr:@std/testing@^1.0.6": "1.0.6", + "jsr:@std/testing@^1.0.8": "1.0.8", "npm:@asteasolutions/zod-to-openapi@^7.3.0": "7.3.0_zod@3.24.1", "npm:@types/node@*": "22.5.4", "npm:path-to-regexp@6.2.1": "6.2.1", @@ -50,8 +50,8 @@ "npm:path-to-regexp" ] }, - "@std/assert@1.0.9": { - "integrity": "a9f0c611a869cc791b26f523eec54c7e187aab7932c2c8e8bea0622d13680dcd", + "@std/assert@1.0.10": { + "integrity": "59b5cbac5bd55459a19045d95cc7c2ff787b4f8527c0dd195078ff6f9481fbb3", "dependencies": [ "jsr:@std/internal" ] @@ -62,11 +62,11 @@ "@std/crypto@1.0.3": { "integrity": "a2a32f51ddef632d299e3879cd027c630dcd4d1d9a5285d6e6788072f4e51e7f" }, - "@std/encoding@1.0.5": { - "integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04" + "@std/encoding@1.0.6": { + "integrity": "ca87122c196e8831737d9547acf001766618e78cd8c33920776c7f5885546069" }, - "@std/fs@1.0.6": { - "integrity": "42b56e1e41b75583a21d5a37f6a6a27de9f510bcd36c0c85791d685ca0b85fa2", + "@std/fs@1.0.8": { + "integrity": "161c721b6f9400b8100a851b6f4061431c538b204bb76c501d02c508995cffe0", "dependencies": [ "jsr:@std/path@^1.0.8" ] @@ -98,10 +98,10 @@ "@std/path@1.0.8": { "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be" }, - "@std/testing@1.0.6": { - "integrity": "9192ded2d34065f4c959fdc1921fe836770abb9194410c2cc8a0fff4eff5c893", + "@std/testing@1.0.8": { + "integrity": "ceef535808fb7568e91b0f8263599bd29b1c5603ffb0377227f00a8ca9fe42a2", "dependencies": [ - "jsr:@std/assert@^1.0.9", + "jsr:@std/assert@^1.0.10", "jsr:@std/fs", "jsr:@std/internal", "jsr:@std/path@^1.0.8" @@ -144,10 +144,10 @@ "workspace": { "dependencies": [ "jsr:@oak/oak@^17.1.3", - "jsr:@std/assert@^1.0.9", + "jsr:@std/assert@^1.0.10", "jsr:@std/io@0.225", "jsr:@std/path@^1.0.8", - "jsr:@std/testing@^1.0.6", + "jsr:@std/testing@^1.0.8", "npm:@asteasolutions/zod-to-openapi@^7.3.0", "npm:zod@^3.24.1" ] diff --git a/src/__snapshots__/useOas_test.ts.snap b/src/__snapshots__/useOas_test.ts.snap index 6371bf0..b8fbe9c 100644 --- a/src/__snapshots__/useOas_test.ts.snap +++ b/src/__snapshots__/useOas_test.ts.snap @@ -1,6 +1,6 @@ export const snapshot = {}; -snapshot[`useOas standard behavior > testApiDocSnapshot 1`] = ` +snapshot[`useOas standard behavior - OpenApi v3.0 > testApiDocSnapshot 1`] = ` { components: { parameters: {}, @@ -15,6 +15,7 @@ snapshot[`useOas standard behavior > testApiDocSnapshot 1`] = ` paths: { "/hello/{name}": { post: { + operationId: undefined, parameters: [ { in: "path", @@ -26,6 +27,7 @@ snapshot[`useOas standard behavior > testApiDocSnapshot 1`] = ` }, ], responses: {}, + tags: undefined, }, }, }, @@ -34,5 +36,65 @@ snapshot[`useOas standard behavior > testApiDocSnapshot 1`] = ` url: "/mock/", }, ], + tags: [ + { + description: "Example description for Example Section", + externalDocs: { + url: "http://localhost", + }, + name: "Example Section", + }, + ], +} +`; + +snapshot[`useOas standard behavior - OpenApi v3.1 > testApiDocSnapshot 1`] = ` +{ + components: { + parameters: {}, + schemas: {}, + }, + info: { + description: "this is a mock API", + title: "mock API", + version: "0.1.0", + }, + openapi: "3.1.0", + paths: { + "/hello/{name}": { + post: { + operationId: "my-unique-test-op-id", + parameters: [ + { + in: "path", + name: "name", + required: true, + schema: { + type: "string", + }, + }, + ], + responses: {}, + tags: [ + "Example Section", + ], + }, + }, + }, + servers: [ + { + url: "/mock/", + }, + ], + tags: [ + { + description: "Example description for Example Section", + externalDocs: { + url: "http://localhost", + }, + name: "Example Section", + }, + ], + webhooks: {}, } `; diff --git a/src/oasStore.ts b/src/oasStore.ts index 369fef1..d802a66 100644 --- a/src/oasStore.ts +++ b/src/oasStore.ts @@ -3,8 +3,12 @@ import type { OakOpenApiSpec } from "./utils/schema_utils.ts"; import type { SupportedVerb } from "./Store.ts"; import { debug } from "./utils/logger.ts"; +type TheRouteConfig = RouteConfig & { + tags?: string[]; +}; + // fnName|method|path => OasRouteConfig -export const oasStore: Map = new Map(); +export const oasStore: Map = new Map(); const getRouteId = ( fnName: string, @@ -62,6 +66,8 @@ export const updateOas = ( ...existing.responses, ...specs?.responses, }, + operationId: specs?.operationId, + tags: specs?.tags, }; debug(`OpenApiSpec: recording for [${method}] ${path}`); diff --git a/src/useOas.ts b/src/useOas.ts index 2c887d5..670b7de 100644 --- a/src/useOas.ts +++ b/src/useOas.ts @@ -2,6 +2,7 @@ import type { Application } from "@oak/oak"; import { oasStore } from "./oasStore.ts"; import { OpenApiGeneratorV3, + OpenApiGeneratorV31, OpenAPIRegistry, type RouteConfig, } from "@asteasolutions/zod-to-openapi"; @@ -34,6 +35,11 @@ export type UseOasConfig = Partial & { jsonPath?: string; uiPath?: string; uiTemplate?: string; + tags?: { + name: string; + description?: string; + externalDocs?: { url: string }; + }[]; }; type UseOas = ( @@ -62,7 +68,11 @@ const _useOas: UseOas = ( } }); - const generator = new OpenApiGeneratorV3(registry.definitions); + const OpenApiGenerator = oasCfg.openapi?.startsWith("3.0") + ? OpenApiGeneratorV3 + : OpenApiGeneratorV31; + + const generator = new OpenApiGenerator(registry.definitions); const apiDoc = generator.generateDocument({ openapi: "3.0.0", info: { diff --git a/src/useOas_test.ts b/src/useOas_test.ts index d9d6cdf..efe441c 100644 --- a/src/useOas_test.ts +++ b/src/useOas_test.ts @@ -2,7 +2,10 @@ import { type Middleware, testing as oakTesting } from "@oak/oak"; import { assertEquals } from "@std/assert"; import { assertSpyCall, assertSpyCalls, spy, stub } from "@std/testing/mock"; import { assertSnapshot } from "@std/testing/snapshot"; -import { OpenApiGeneratorV3 } from "@asteasolutions/zod-to-openapi"; +import { + OpenApiGeneratorV3, + OpenApiGeneratorV31, +} from "@asteasolutions/zod-to-openapi"; import { z } from "./utils/schema_utils.ts"; import { oasStore, updateOas } from "./oasStore.ts"; import { _internal, useOas } from "./useOas.ts"; @@ -29,7 +32,8 @@ Deno.test("useOas with a non-conforming Application instance", () => { ' info: { version: "1.0.0", title: "My API", description: "This is the API" },\n' + ' servers: [ { url: "/" } ],\n' + " components: { schemas: {}, parameters: {} },\n" + - " paths: {}\n" + + " paths: {},\n" + + " webhooks: {}\n" + "}", ], }); @@ -73,7 +77,7 @@ Deno.test("useOas with empty definitions", () => { assertEquals(_internal.registry.definitions, []); }); -Deno.test("useOas standard behavior", async (t) => { +Deno.test("useOas standard behavior - OpenApi v3.0", async (t) => { const fnName = "doSomething"; const method = "post"; const path = "/hello/:name"; @@ -98,6 +102,13 @@ Deno.test("useOas standard behavior", async (t) => { description: "this is a mock API", }, servers: [{ url: "/mock/" }], + tags: [{ + name: "Example Section", + description: "Example description for Example Section", + externalDocs: { + url: "http://localhost", + }, + }], }; let apiDoc; @@ -148,3 +159,88 @@ Deno.test("useOas standard behavior", async (t) => { ), ); }); + +Deno.test("useOas standard behavior - OpenApi v3.1", async (t) => { + const fnName = "doSomething"; + const method = "post"; + const path = "/hello/:name"; + + updateOas(fnName, method, path, { + request: { + params: z.object({ name: z.string() }), + }, + operationId: "my-unique-test-op-id", + tags: ["Example Section"], + }); + + const uiPath = "/my/swagger-31"; + const uiTemplate = "mock"; + const jsonPath = "/my/swagger-31/json"; + const oasConfig = { + uiPath, + uiTemplate, + jsonPath, + openapi: "3.1.0", + info: { + version: "0.1.0", + title: "mock API", + description: "this is a mock API", + }, + servers: [{ url: "/mock/" }], + tags: [{ + name: "Example Section", + description: "Example description for Example Section", + externalDocs: { + url: "http://localhost", + }, + }], + }; + let apiDoc; + + await t.step(async function testApiDocSnapshot(t) { + const mockCtx = createMockContext(); + useOas(mockCtx.app, oasConfig); + const generator = new OpenApiGeneratorV31(_internal.registry.definitions); + const { + jsonPath: _jsonPath, + uiPath: _uiPath, + uiTemplate: _uiTemplate, + ...oasCfg + } = oasConfig; + apiDoc = generator.generateDocument(oasCfg); + await assertSnapshot(t, apiDoc); + }); + + const cases: { mockRequestPath: string; expectedResponseBody: unknown }[] = [{ + mockRequestPath: uiPath, + expectedResponseBody: uiTemplate, + }, { + mockRequestPath: jsonPath, + expectedResponseBody: apiDoc, + }]; + + await Promise.all( + cases.map(({ mockRequestPath, expectedResponseBody }) => + t.step({ + name: `request oasMiddleware at ${mockRequestPath}`, + fn: async () => { + const mockCtx = createMockContext(); + mockRequestInternals(mockCtx.request, { mockRequestPath }); + const mockNxt = spy(() => Promise.resolve()); + const spyAppUse = spy(mockCtx.app, "use"); + + useOas(mockCtx.app, oasConfig); + + const oasMiddleware = spyAppUse.calls[0].args[0] as Middleware; + await oasMiddleware(mockCtx, mockNxt); + + assertSpyCalls(mockNxt, 1); + assertEquals(mockCtx.response.body, expectedResponseBody); + }, + sanitizeOps: false, + sanitizeResources: false, + sanitizeExit: false, + }) + ), + ); +}); From 05e4543e6462ff5a6b189e4fff8a5a2b8843bed3 Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Sat, 1 Feb 2025 14:39:31 +0100 Subject: [PATCH 13/14] upgraded deps --- CHANGELOG.md | 4 ++- deno.jsonc | 8 ++--- deno.lock | 92 ++++++++++++++++++++++++---------------------------- 3 files changed, 49 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e8e903..8ab96bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## Unreleased +## [0.13.0] - 2025-02-01 ### Added @@ -18,6 +18,8 @@ `@std/testing@^1.0.8`) - updated typing for `OakOpenApiSpec` (added prop: `request`, untyped unproven prop: `requestBody`) +- upgraded dependencies: `jsr:@oak/oak@^17.1.4`, `jsr:@std/assert@^1.0.11`, + `jsr:@std/io@^0.225.2`, `jsr:@std/testing@^1.0.9` ## Removed diff --git a/deno.jsonc b/deno.jsonc index 3701d34..47a803d 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -21,11 +21,11 @@ }, "imports": { "@asteasolutions/zod-to-openapi": "npm:@asteasolutions/zod-to-openapi@^7.3.0", - "@oak/oak": "jsr:@oak/oak@^17.1.3", - "@std/assert": "jsr:@std/assert@^1.0.10", - "@std/io": "jsr:@std/io@^0.225.0", + "@oak/oak": "jsr:@oak/oak@^17.1.4", + "@std/assert": "jsr:@std/assert@^1.0.11", + "@std/io": "jsr:@std/io@^0.225.2", "@std/path": "jsr:@std/path@^1.0.8", - "@std/testing": "jsr:@std/testing@^1.0.8", + "@std/testing": "jsr:@std/testing@^1.0.9", "zod": "npm:zod@^3.24.1" }, "fmt": { diff --git a/deno.lock b/deno.lock index ee9028c..7e46502 100644 --- a/deno.lock +++ b/deno.lock @@ -2,26 +2,26 @@ "version": "4", "specifiers": { "jsr:@oak/commons@1": "1.0.0", - "jsr:@oak/oak@^17.1.3": "17.1.3", - "jsr:@std/assert@1": "1.0.10", - "jsr:@std/assert@^1.0.10": "1.0.10", - "jsr:@std/bytes@1": "1.0.4", - "jsr:@std/bytes@^1.0.2": "1.0.4", - "jsr:@std/crypto@1": "1.0.3", - "jsr:@std/encoding@1": "1.0.6", - "jsr:@std/encoding@^1.0.5": "1.0.6", - "jsr:@std/fs@^1.0.8": "1.0.8", - "jsr:@std/http@1": "1.0.12", + "jsr:@oak/oak@^17.1.4": "17.1.4", + "jsr:@std/assert@1": "1.0.11", + "jsr:@std/assert@^1.0.10": "1.0.11", + "jsr:@std/assert@^1.0.11": "1.0.11", + "jsr:@std/bytes@1": "1.0.5", + "jsr:@std/bytes@^1.0.5": "1.0.5", + "jsr:@std/crypto@1": "1.0.4", + "jsr:@std/encoding@1": "1.0.7", + "jsr:@std/encoding@^1.0.7": "1.0.7", + "jsr:@std/fs@^1.0.9": "1.0.11", + "jsr:@std/http@1": "1.0.13", "jsr:@std/internal@^1.0.5": "1.0.5", - "jsr:@std/io@0.224": "0.224.9", - "jsr:@std/io@0.225": "0.225.0", + "jsr:@std/io@~0.225.2": "0.225.2", "jsr:@std/media-types@1": "1.1.0", "jsr:@std/path@1": "1.0.8", "jsr:@std/path@^1.0.8": "1.0.8", - "jsr:@std/testing@^1.0.8": "1.0.8", + "jsr:@std/testing@^1.0.9": "1.0.9", "npm:@asteasolutions/zod-to-openapi@^7.3.0": "7.3.0_zod@3.24.1", "npm:@types/node@*": "22.5.4", - "npm:path-to-regexp@6.2.1": "6.2.1", + "npm:path-to-regexp@^6.3.0": "6.3.0", "npm:zod@^3.24.1": "3.24.1" }, "jsr": { @@ -36,60 +36,52 @@ "jsr:@std/media-types" ] }, - "@oak/oak@17.1.3": { - "integrity": "d89296c22db91681dd3a2a1e1fd14e258d0d5a9654de55637aee5b661c159f33", + "@oak/oak@17.1.4": { + "integrity": "60530b582bf276ff741e39cc664026781aa08dd5f2bc5134d756cc427bf2c13e", "dependencies": [ "jsr:@oak/commons", "jsr:@std/assert@1", "jsr:@std/bytes@1", - "jsr:@std/crypto", "jsr:@std/http", - "jsr:@std/io@0.224", "jsr:@std/media-types", "jsr:@std/path@1", "npm:path-to-regexp" ] }, - "@std/assert@1.0.10": { - "integrity": "59b5cbac5bd55459a19045d95cc7c2ff787b4f8527c0dd195078ff6f9481fbb3", + "@std/assert@1.0.11": { + "integrity": "2461ef3c368fe88bc60e186e7744a93112f16fd110022e113a0849e94d1c83c1", "dependencies": [ "jsr:@std/internal" ] }, - "@std/bytes@1.0.4": { - "integrity": "11a0debe522707c95c7b7ef89b478c13fb1583a7cfb9a85674cd2cc2e3a28abc" + "@std/bytes@1.0.5": { + "integrity": "4465dd739d7963d964c809202ebea6d5c6b8e3829ef25c6a224290fbb8a1021e" }, - "@std/crypto@1.0.3": { - "integrity": "a2a32f51ddef632d299e3879cd027c630dcd4d1d9a5285d6e6788072f4e51e7f" + "@std/crypto@1.0.4": { + "integrity": "cee245c453bd5366207f4d8aa25ea3e9c86cecad2be3fefcaa6cb17203d79340" }, - "@std/encoding@1.0.6": { - "integrity": "ca87122c196e8831737d9547acf001766618e78cd8c33920776c7f5885546069" + "@std/encoding@1.0.7": { + "integrity": "f631247c1698fef289f2de9e2a33d571e46133b38d042905e3eac3715030a82d" }, - "@std/fs@1.0.8": { - "integrity": "161c721b6f9400b8100a851b6f4061431c538b204bb76c501d02c508995cffe0", + "@std/fs@1.0.11": { + "integrity": "ba674672693340c5ebdd018b4fe1af46cb08741f42b4c538154e97d217b55bdd", "dependencies": [ "jsr:@std/path@^1.0.8" ] }, - "@std/http@1.0.12": { - "integrity": "85246d8bfe9c8e2538518725b158bdc31f616e0869255f4a8d9e3de919cab2aa", + "@std/http@1.0.13": { + "integrity": "d29618b982f7ae44380111f7e5b43da59b15db64101198bb5f77100d44eb1e1e", "dependencies": [ - "jsr:@std/encoding@^1.0.5" + "jsr:@std/encoding@^1.0.7" ] }, "@std/internal@1.0.5": { "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba" }, - "@std/io@0.224.9": { - "integrity": "4414664b6926f665102e73c969cfda06d2c4c59bd5d0c603fd4f1b1c840d6ee3", - "dependencies": [ - "jsr:@std/bytes@^1.0.2" - ] - }, - "@std/io@0.225.0": { - "integrity": "c1db7c5e5a231629b32d64b9a53139445b2ca640d828c26bf23e1c55f8c079b3", + "@std/io@0.225.2": { + "integrity": "3c740cd4ee4c082e6cfc86458f47e2ab7cb353dc6234d5e9b1f91a2de5f4d6c7", "dependencies": [ - "jsr:@std/bytes@^1.0.2" + "jsr:@std/bytes@^1.0.5" ] }, "@std/media-types@1.1.0": { @@ -98,8 +90,8 @@ "@std/path@1.0.8": { "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be" }, - "@std/testing@1.0.8": { - "integrity": "ceef535808fb7568e91b0f8263599bd29b1c5603ffb0377227f00a8ca9fe42a2", + "@std/testing@1.0.9": { + "integrity": "9bdd4ac07cb13e7594ac30e90f6ceef7254ac83a9aeaa089be0008f33aab5cd4", "dependencies": [ "jsr:@std/assert@^1.0.10", "jsr:@std/fs", @@ -128,14 +120,14 @@ "yaml" ] }, - "path-to-regexp@6.2.1": { - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + "path-to-regexp@6.3.0": { + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==" }, "undici-types@6.19.8": { "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" }, - "yaml@2.6.1": { - "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==" + "yaml@2.7.0": { + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==" }, "zod@3.24.1": { "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==" @@ -143,11 +135,11 @@ }, "workspace": { "dependencies": [ - "jsr:@oak/oak@^17.1.3", - "jsr:@std/assert@^1.0.10", - "jsr:@std/io@0.225", + "jsr:@oak/oak@^17.1.4", + "jsr:@std/assert@^1.0.11", + "jsr:@std/io@~0.225.2", "jsr:@std/path@^1.0.8", - "jsr:@std/testing@^1.0.8", + "jsr:@std/testing@^1.0.9", "npm:@asteasolutions/zod-to-openapi@^7.3.0", "npm:zod@^3.24.1" ] From d065b7c6d9f6af3bd9176ced46df4ef157ff9aa3 Mon Sep 17 00:00:00 2001 From: dk <2597375+Thesephi@users.noreply.github.com> Date: Sat, 1 Feb 2025 14:41:40 +0100 Subject: [PATCH 14/14] version bump --- deno.jsonc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deno.jsonc b/deno.jsonc index 47a803d..644b9e9 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,6 +1,6 @@ { "name": "@dklab/oak-routing-ctrl", - "version": "0.13.0-rc.1", + "version": "0.13.0", "exports": { ".": "./mod.ts", "./mod": "./mod.ts"