diff --git a/jsr.json b/jsr.json index 16ac6ee..afe980a 100644 --- a/jsr.json +++ b/jsr.json @@ -2,7 +2,10 @@ "$schema": "https://jsr.io/schema/config-file.v1.json", "name": "@exuanbo/di-wise", "version": "0.2.6", - "exports": "./src/index.ts", + "exports": { + ".": "./src/index.ts", + "./middlewares": "./src/middlewares/index.ts" + }, "publish": { "include": ["src", "!src/__tests__", "LICENSE", "README.md", "tsconfig.json"] } diff --git a/package.json b/package.json index f44d8f6..f6b2203 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,16 @@ "types": "./dist/cjs/index.d.ts", "default": "./dist/cjs/index.js" } + }, + "./middlewares": { + "import": { + "types": "./dist/es/middlewares.d.mts", + "default": "./dist/es/middlewares.mjs" + }, + "require": { + "types": "./dist/cjs/middlewares.d.ts", + "default": "./dist/cjs/middlewares.js" + } } }, "sideEffects": false, @@ -31,7 +41,7 @@ "lint:ci": "eslint . --max-warnings 0 --cache --cache-location ./node_modules/.cache/eslint/.eslintcache", "format": "prettier \"**/*.{json,md,yml}\" --write --log-level warn --cache", "format:check": "prettier \"**/*.{json,md,yml}\" --check --cache", - "typedoc": "typedoc src/index.ts --includeVersion" + "typedoc": "typedoc src/index.ts src/middlewares/index.ts --includeVersion" }, "repository": { "type": "git", diff --git a/src/__tests__/middleware.spec.ts b/src/__tests__/middleware.spec.ts index 9742d31..ccf920f 100644 --- a/src/__tests__/middleware.spec.ts +++ b/src/__tests__/middleware.spec.ts @@ -1,6 +1,16 @@ import {beforeEach, describe, expect, it, vi} from "vitest"; -import {applyMiddleware, type Container, createContainer, inject, injectAll, type Middleware, type Token} from ".."; +import { + applyMiddleware, + type Container, + createContainer, + inject, + injectAll, + type Middleware, + type Token, + Type, +} from ".."; +import {resolveAllSafe} from "../middlewares"; describe("Middleware", () => { let container: Container; @@ -78,4 +88,18 @@ describe("Middleware", () => { ["[B] post resolve Wizard {wand: Wand {decorations: [Decoration {}]}}"], ]); }); + + describe("resolveAllOptional", () => { + it("should resolve all tokens to empty array if they are not provided", () => { + applyMiddleware(container, [resolveAllSafe]); + + const NonRegistered = Type("NonRegistered"); + expect(container.resolveAll(NonRegistered)).toEqual([]); + + const Registered = Type("Registered"); + container.register(Registered, {useValue: "Success"}); + + expect(container.resolveAll(Registered)).toEqual(["Success"]); + }); + }); }); diff --git a/src/middlewares/index.ts b/src/middlewares/index.ts new file mode 100644 index 0000000..99fd43a --- /dev/null +++ b/src/middlewares/index.ts @@ -0,0 +1 @@ +export {resolveAllSafe} from "./resolve-all-safe"; diff --git a/src/middlewares/resolve-all-safe.ts b/src/middlewares/resolve-all-safe.ts new file mode 100644 index 0000000..675f29a --- /dev/null +++ b/src/middlewares/resolve-all-safe.ts @@ -0,0 +1,22 @@ +import {type Middleware, type Token, Type} from "../index"; + +/** + * Middleware that makes `resolveAll` return an empty array for unregistered tokens instead of throwing. + * + * This middleware modifies the behavior of `resolveAll` to safely handle cases where tokens haven't been + * registered in the container. Instead of throwing an error, it will return an empty array. + * + * @example + * ```ts + * import {resolveAllSafe} from "di-wise/middlewares"; + * + * const container = applyMiddleware(createContainer(), [resolveAllSafe]); + * + * container.resolveAll(NonRegisteredToken); // => [] + * ``` + */ +export const resolveAllSafe: Middleware = (composer) => { + composer.use("resolveAll", (next) => (...args: Token[]) => { + return next(...args, Type.Null); + }); +};