decorator-dependency-injection 1.0.7 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -19
- package/docs/FRAMEWORK_INTEGRATION.md +808 -0
- package/eslint.config.js +4 -1
- package/index.d.ts +6 -355
- package/index.js +46 -378
- package/package.json +6 -1
- package/src/Container.js +48 -201
- package/src/integrations/middleware.d.ts +40 -0
- package/src/integrations/middleware.js +171 -0
package/README.md
CHANGED
|
@@ -15,7 +15,11 @@ No reflection. No metadata. No configuration files. Just decorators that work.
|
|
|
15
15
|
- Zero dependencies - tiny bundle size
|
|
16
16
|
- Built-in mocking support for unit testing with Jest, Vitest, or Mocha
|
|
17
17
|
- Full TypeScript support with type inference
|
|
18
|
-
- Works with Node.js,
|
|
18
|
+
- Works with Node.js, Bun, React, Vue, Svelte, and more
|
|
19
|
+
|
|
20
|
+
> **Using a frontend framework?** See the [Framework Integration Guide](docs/FRAMEWORK_INTEGRATION.md) for React, Vue, Svelte, SSR, and other environments.
|
|
21
|
+
|
|
22
|
+
> **Building a Node.js server?** We have [Express/Koa/Fastify middleware](docs/FRAMEWORK_INTEGRATION.md#nodejs-server-middleware) for automatic request-scoped containers.
|
|
19
23
|
|
|
20
24
|
## Table of Contents
|
|
21
25
|
|
|
@@ -38,6 +42,7 @@ No reflection. No metadata. No configuration files. Just decorators that work.
|
|
|
38
42
|
- [Manual Resolution](#manual-resolution)
|
|
39
43
|
- [Container Introspection](#container-introspection)
|
|
40
44
|
- [Isolated Containers](#isolated-containers)
|
|
45
|
+
- [Server Middleware](#server-middleware-expresskoa-fastify)
|
|
41
46
|
- [API Reference](#api-reference)
|
|
42
47
|
- [TypeScript Support](#typescript-support)
|
|
43
48
|
|
|
@@ -81,7 +86,7 @@ Add to your `.babelrc` or `babel.config.json`:
|
|
|
81
86
|
|
|
82
87
|
```json
|
|
83
88
|
{
|
|
84
|
-
"plugins": ["@babel/plugin-proposal-decorators"]
|
|
89
|
+
"plugins": [["@babel/plugin-proposal-decorators", { "version": "2023-11" }]]
|
|
85
90
|
}
|
|
86
91
|
```
|
|
87
92
|
|
|
@@ -424,6 +429,42 @@ container.registerSingleton(MyService)
|
|
|
424
429
|
const instance = container.resolve(MyService)
|
|
425
430
|
```
|
|
426
431
|
|
|
432
|
+
See the [Framework Integration Guide](docs/FRAMEWORK_INTEGRATION.md#server-side-rendering) for SSR request isolation patterns.
|
|
433
|
+
|
|
434
|
+
### Server Middleware (Express/Koa/Fastify)
|
|
435
|
+
|
|
436
|
+
For Node.js servers, use the middleware module to get **automatic request-scoped containers**:
|
|
437
|
+
|
|
438
|
+
```javascript
|
|
439
|
+
import express from 'express'
|
|
440
|
+
import { containerMiddleware, resolve } from 'decorator-dependency-injection/middleware'
|
|
441
|
+
|
|
442
|
+
const app = express()
|
|
443
|
+
app.use(containerMiddleware())
|
|
444
|
+
|
|
445
|
+
app.get('/user/:id', (req, res) => {
|
|
446
|
+
// Each request gets its own isolated container
|
|
447
|
+
const userService = resolve(UserService)
|
|
448
|
+
res.json(userService.getUser(req.params.id))
|
|
449
|
+
})
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
**Mixing Global and Request Scopes:**
|
|
453
|
+
|
|
454
|
+
```javascript
|
|
455
|
+
app.get('/data', (req, res) => {
|
|
456
|
+
// Use global singleton (e.g., database pool, config)
|
|
457
|
+
const db = resolve(DatabasePool, { scope: 'global' })
|
|
458
|
+
|
|
459
|
+
// Use request-scoped service (default)
|
|
460
|
+
const userService = resolve(UserService)
|
|
461
|
+
|
|
462
|
+
res.json(userService.getData(db))
|
|
463
|
+
})
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
See the [Framework Integration Guide](docs/FRAMEWORK_INTEGRATION.md#nodejs-server-middleware) for Koa, Fastify, and advanced patterns.
|
|
467
|
+
|
|
427
468
|
---
|
|
428
469
|
|
|
429
470
|
## API Reference
|
|
@@ -432,30 +473,56 @@ const instance = container.resolve(MyService)
|
|
|
432
473
|
|
|
433
474
|
| Decorator | Description |
|
|
434
475
|
|-----------|-------------|
|
|
435
|
-
| `@Singleton(name?)` | Register a class as a singleton |
|
|
436
|
-
| `@Factory(name?)` | Register a class as a factory |
|
|
437
|
-
| `@Inject(target, ...params)` | Inject a dependency into a field |
|
|
438
|
-
| `@InjectLazy(target, ...params)` | Inject lazily (on first access) |
|
|
439
|
-
| `@Mock(target, proxy?)` | Replace a dependency with a mock |
|
|
476
|
+
| `@Singleton(name?)` | Register a class as a singleton ([example](#singleton)) |
|
|
477
|
+
| `@Factory(name?)` | Register a class as a factory ([example](#factory)) |
|
|
478
|
+
| `@Inject(target, ...params)` | Inject a dependency into a field ([example](#singleton)) |
|
|
479
|
+
| `@InjectLazy(target, ...params)` | Inject lazily (on first access) ([example](#lazy-injection)) |
|
|
480
|
+
| `@Mock(target, proxy?)` | Replace a dependency with a mock ([example](#mocking-dependencies)) |
|
|
440
481
|
|
|
441
482
|
### Functions
|
|
442
483
|
|
|
443
484
|
| Function | Description |
|
|
444
485
|
|----------|-------------|
|
|
445
|
-
| `resolve(target, ...params)` | Get an instance from the container |
|
|
446
|
-
| `removeMock(target)` | Remove a mock, restore original |
|
|
447
|
-
| `removeAllMocks()` | Remove all mocks |
|
|
448
|
-
| `resetSingletons(options?)` | Clear cached singleton instances |
|
|
449
|
-
| `clearContainer(options?)` | Clear all registrations |
|
|
450
|
-
| `isRegistered(target)` | Check if target is registered |
|
|
451
|
-
| `isMocked(target)` | Check if target is mocked |
|
|
452
|
-
| `getMockInstance(target)` | Get the mock instance |
|
|
453
|
-
| `validateRegistrations(...targets)` | Throw if any target is not registered |
|
|
454
|
-
| `listRegistrations()` | List all registrations |
|
|
455
|
-
| `getContainer()` | Get the default container |
|
|
456
|
-
| `setDebug(enabled)` | Enable/disable debug logging |
|
|
486
|
+
| `resolve(target, ...params)` | Get an instance from the container ([example](#manual-resolution)) |
|
|
487
|
+
| `removeMock(target)` | Remove a mock, restore original ([example](#mocking-dependencies)) |
|
|
488
|
+
| `removeAllMocks()` | Remove all mocks ([example](#test-lifecycle)) |
|
|
489
|
+
| `resetSingletons(options?)` | Clear cached singleton instances ([example](#test-lifecycle)) |
|
|
490
|
+
| `clearContainer(options?)` | Clear all registrations ([example](#test-lifecycle)) |
|
|
491
|
+
| `isRegistered(target)` | Check if target is registered ([example](#container-introspection)) |
|
|
492
|
+
| `isMocked(target)` | Check if target is mocked ([example](#testing-best-practices)) |
|
|
493
|
+
| `getMockInstance(target)` | Get the mock instance ([example](#testing-best-practices)) |
|
|
494
|
+
| `validateRegistrations(...targets)` | Throw if any target is not registered ([example](#container-introspection)) |
|
|
495
|
+
| `listRegistrations()` | List all registrations ([example](#container-introspection)) |
|
|
496
|
+
| `getContainer()` | Get the default container ([example](#isolated-containers)) |
|
|
497
|
+
| `setDebug(enabled)` | Enable/disable debug logging ([example](#container-introspection)) |
|
|
457
498
|
| `unregister(target)` | Remove a registration |
|
|
458
499
|
|
|
500
|
+
### Middleware Functions (`/middleware`)
|
|
501
|
+
|
|
502
|
+
| Function | Description |
|
|
503
|
+
|----------|-------------|
|
|
504
|
+
| `containerMiddleware(options?)` | Express/Fastify middleware ([example](#server-middleware-expresskoafastify)) |
|
|
505
|
+
| `koaContainerMiddleware(options?)` | Koa middleware ([example](docs/FRAMEWORK_INTEGRATION.md#koa)) |
|
|
506
|
+
| `resolve(target, options?)` | Get instance from request or global container ([example](#server-middleware-expresskoafastify)) |
|
|
507
|
+
| `getContainer()` | Get current request container (or global if outside request) |
|
|
508
|
+
| `getGlobalContainer()` | Get the global container |
|
|
509
|
+
| `runWithContainer(container, fn, options?)` | Run function with specific container ([example](docs/FRAMEWORK_INTEGRATION.md#testing-with-runwithcontainer)) |
|
|
510
|
+
| `withContainer(options?)` | Wrap handler with container context ([example](docs/FRAMEWORK_INTEGRATION.md#hono--fastify-handler-wrapper)) |
|
|
511
|
+
|
|
512
|
+
**Middleware Options:**
|
|
513
|
+
|
|
514
|
+
| Option | Type | Description |
|
|
515
|
+
|--------|------|-------------|
|
|
516
|
+
| `scope` | `'request' \| 'global'` | Container scope (default: `'request'`) |
|
|
517
|
+
| `debug` | `boolean` | Enable debug logging |
|
|
518
|
+
|
|
519
|
+
**Resolve Options:**
|
|
520
|
+
|
|
521
|
+
| Option | Type | Description |
|
|
522
|
+
|--------|------|-------------|
|
|
523
|
+
| `scope` | `'request' \| 'global'` | Which container to resolve from (default: `'request'`) |
|
|
524
|
+
| `params` | `any[]` | Constructor parameters to pass when creating instance |
|
|
525
|
+
|
|
459
526
|
---
|
|
460
527
|
|
|
461
528
|
## TypeScript Support
|
|
@@ -508,3 +575,4 @@ Searching for: JavaScript dependency injection, TypeScript DI container, decorat
|
|
|
508
575
|
- 1.0.5 - Added private field and accessor support for @Inject and @InjectLazy, debug mode, validation helpers
|
|
509
576
|
- 1.0.6 - Added resolve() function for non-decorator code
|
|
510
577
|
- 1.0.7 - Added more control for mocking in tests and improved compatibility
|
|
578
|
+
- 1.1.0 - Added framework integration guide and server middleware
|