@venizia/ignis-docs 0.2.0 → 0.2.1-1

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.
Files changed (174) hide show
  1. package/README.md +14 -14
  2. package/content/best-practices/api-usage-examples.md +39 -19
  3. package/content/best-practices/architectural-patterns.md +24 -13
  4. package/content/best-practices/architecture-decisions.md +29 -16
  5. package/content/best-practices/code-style-standards/advanced-patterns.md +43 -31
  6. package/content/best-practices/code-style-standards/constants-configuration.md +19 -4
  7. package/content/best-practices/code-style-standards/control-flow.md +33 -1
  8. package/content/best-practices/code-style-standards/documentation.md +28 -8
  9. package/content/best-practices/code-style-standards/function-patterns.md +15 -4
  10. package/content/best-practices/code-style-standards/index.md +7 -2
  11. package/content/best-practices/code-style-standards/naming-conventions.md +27 -3
  12. package/content/best-practices/code-style-standards/route-definitions.md +9 -5
  13. package/content/best-practices/code-style-standards/tooling.md +14 -1
  14. package/content/best-practices/code-style-standards/type-safety.md +39 -6
  15. package/content/best-practices/common-pitfalls.md +59 -35
  16. package/content/best-practices/contribution-workflow.md +8 -4
  17. package/content/best-practices/data-modeling.md +78 -62
  18. package/content/best-practices/deployment-strategies.md +56 -19
  19. package/content/best-practices/error-handling.md +247 -153
  20. package/content/best-practices/index.md +6 -0
  21. package/content/best-practices/performance-optimization.md +26 -13
  22. package/content/best-practices/security-guidelines.md +35 -9
  23. package/content/best-practices/testing-strategies.md +7 -2
  24. package/content/best-practices/troubleshooting-tips.md +27 -17
  25. package/content/extensions/components/api-reference.md +109 -323
  26. package/content/extensions/components/authentication/api.md +489 -602
  27. package/content/extensions/components/authentication/errors.md +135 -498
  28. package/content/extensions/components/authentication/index.md +89 -801
  29. package/content/extensions/components/authentication/usage.md +231 -955
  30. package/content/extensions/components/authorization/api.md +991 -644
  31. package/content/extensions/components/authorization/errors.md +204 -208
  32. package/content/extensions/components/authorization/getting-started.md +227 -0
  33. package/content/extensions/components/authorization/index.md +88 -795
  34. package/content/extensions/components/authorization/usage.md +219 -528
  35. package/content/extensions/components/health-check.md +77 -243
  36. package/content/extensions/components/index.md +24 -90
  37. package/content/extensions/components/mail/api.md +553 -285
  38. package/content/extensions/components/mail/errors.md +76 -62
  39. package/content/extensions/components/mail/index.md +111 -463
  40. package/content/extensions/components/mail/usage.md +139 -173
  41. package/content/extensions/components/request-tracker.md +70 -173
  42. package/content/extensions/components/socket-io/api.md +462 -785
  43. package/content/extensions/components/socket-io/errors.md +49 -51
  44. package/content/extensions/components/socket-io/index.md +69 -372
  45. package/content/extensions/components/socket-io/usage.md +212 -105
  46. package/content/extensions/components/static-asset/api.md +461 -141
  47. package/content/extensions/components/static-asset/errors.md +121 -53
  48. package/content/extensions/components/static-asset/index.md +84 -606
  49. package/content/extensions/components/static-asset/usage.md +184 -299
  50. package/content/extensions/components/template/index.md +3 -3
  51. package/content/extensions/components/websocket/api.md +311 -404
  52. package/content/extensions/components/websocket/errors.md +47 -56
  53. package/content/extensions/components/websocket/index.md +75 -407
  54. package/content/extensions/components/websocket/usage.md +120 -338
  55. package/content/extensions/helpers/cron/index.md +52 -160
  56. package/content/extensions/helpers/crypto/index.md +67 -480
  57. package/content/extensions/helpers/crypto/reference.md +528 -0
  58. package/content/extensions/helpers/env/index.md +64 -178
  59. package/content/extensions/helpers/error/index.md +286 -196
  60. package/content/extensions/helpers/index.md +61 -47
  61. package/content/extensions/helpers/inversion/index.md +76 -550
  62. package/content/extensions/helpers/inversion/reference.md +530 -0
  63. package/content/extensions/helpers/kafka/admin.md +23 -3
  64. package/content/extensions/helpers/kafka/compile-binary.md +83 -52
  65. package/content/extensions/helpers/kafka/consumer.md +65 -28
  66. package/content/extensions/helpers/kafka/examples.md +46 -253
  67. package/content/extensions/helpers/kafka/index.md +55 -617
  68. package/content/extensions/helpers/kafka/producer.md +156 -22
  69. package/content/extensions/helpers/kafka/schema-registry.md +59 -79
  70. package/content/extensions/helpers/logger/hf-logger.md +220 -0
  71. package/content/extensions/helpers/logger/index.md +78 -552
  72. package/content/extensions/helpers/logger/pino.md +105 -0
  73. package/content/extensions/helpers/logger/reference.md +937 -0
  74. package/content/extensions/helpers/network/api.md +276 -195
  75. package/content/extensions/helpers/network/index.md +87 -524
  76. package/content/extensions/helpers/queue/index.md +80 -897
  77. package/content/extensions/helpers/queue/reference.md +494 -0
  78. package/content/extensions/helpers/redis/index.md +86 -640
  79. package/content/extensions/helpers/redis/reference.md +784 -0
  80. package/content/extensions/helpers/secrets/index.md +136 -0
  81. package/content/extensions/helpers/socket-io/api.md +325 -204
  82. package/content/extensions/helpers/socket-io/index.md +79 -429
  83. package/content/extensions/helpers/storage/api.md +584 -464
  84. package/content/extensions/helpers/storage/index.md +80 -573
  85. package/content/extensions/helpers/types/index.md +75 -495
  86. package/content/extensions/helpers/types/reference.md +689 -0
  87. package/content/extensions/helpers/uid/index.md +176 -189
  88. package/content/extensions/helpers/websocket/api.md +366 -214
  89. package/content/extensions/helpers/websocket/index.md +68 -503
  90. package/content/extensions/helpers/worker-thread/index.md +62 -396
  91. package/content/extensions/helpers/worker-thread/reference.md +428 -0
  92. package/content/extensions/index.md +38 -39
  93. package/content/extensions/src-details/mcp-server.md +96 -548
  94. package/content/guides/core-concepts/persistent/datasources.md +2 -2
  95. package/content/guides/core-concepts/persistent/index.md +5 -1
  96. package/content/guides/core-concepts/persistent/models.md +1 -1
  97. package/content/guides/core-concepts/persistent/pglite.md +218 -0
  98. package/content/guides/core-concepts/persistent/postgres-drivers.md +21 -15
  99. package/content/guides/core-concepts/persistent/search-meilisearch.md +22 -12
  100. package/content/guides/core-concepts/persistent/search-typesense.md +28 -16
  101. package/content/guides/core-concepts/persistent/sqlite.md +296 -0
  102. package/content/guides/core-concepts/persistent/transactions.md +12 -11
  103. package/content/guides/core-concepts/secrets-vault.md +177 -0
  104. package/content/guides/core-concepts/services.md +1 -1
  105. package/content/guides/get-started/5-minute-quickstart.md +59 -206
  106. package/content/guides/get-started/philosophy.md +135 -670
  107. package/content/guides/get-started/setup.md +53 -74
  108. package/content/guides/migrations/redis-helpers-migration.md +5 -4
  109. package/content/guides/migrations/scoped-rbac-migration.md +5 -5
  110. package/content/guides/migrations/unified-connectors-migration.md +8 -7
  111. package/content/guides/tutorials/ecommerce-api.md +3 -8
  112. package/content/guides/tutorials/realtime-chat.md +1 -1
  113. package/content/references/base/application.md +64 -22
  114. package/content/references/base/components.md +3 -3
  115. package/content/references/base/connectors.md +79 -136
  116. package/content/references/base/controllers.md +12 -12
  117. package/content/references/base/datasources-reference.md +600 -0
  118. package/content/references/base/datasources.md +84 -444
  119. package/content/references/base/dependency-injection.md +25 -46
  120. package/content/references/base/filter-system/application-usage.md +95 -123
  121. package/content/references/base/filter-system/array-operators.md +33 -43
  122. package/content/references/base/filter-system/comparison-operators.md +55 -63
  123. package/content/references/base/filter-system/default-filter.md +144 -350
  124. package/content/references/base/filter-system/fields-order-pagination.md +116 -148
  125. package/content/references/base/filter-system/index.md +114 -253
  126. package/content/references/base/filter-system/json-filtering.md +52 -181
  127. package/content/references/base/filter-system/list-operators.md +28 -44
  128. package/content/references/base/filter-system/logical-operators.md +69 -114
  129. package/content/references/base/filter-system/null-operators.md +41 -98
  130. package/content/references/base/filter-system/pattern-matching.md +48 -51
  131. package/content/references/base/filter-system/quick-reference.md +93 -196
  132. package/content/references/base/filter-system/range-operators.md +22 -38
  133. package/content/references/base/filter-system/tips.md +70 -133
  134. package/content/references/base/filter-system/use-cases.md +173 -232
  135. package/content/references/base/grpc-controllers.md +53 -17
  136. package/content/references/base/index.md +5 -3
  137. package/content/references/base/middlewares.md +43 -28
  138. package/content/references/base/models-reference.md +886 -0
  139. package/content/references/base/models.md +81 -1452
  140. package/content/references/base/providers.md +8 -8
  141. package/content/references/base/repositories/advanced.md +281 -419
  142. package/content/references/base/repositories/index.md +84 -644
  143. package/content/references/base/repositories/mixins.md +25 -21
  144. package/content/references/base/repositories/relations.md +194 -375
  145. package/content/references/base/repositories/soft-deletable.md +67 -55
  146. package/content/references/base/secrets.md +267 -0
  147. package/content/references/base/services.md +8 -6
  148. package/content/references/configuration/environment-variables.md +73 -21
  149. package/content/references/configuration/index.md +51 -31
  150. package/content/references/index.md +1 -1
  151. package/content/references/quick-reference.md +3 -16
  152. package/content/references/utilities/crypto.md +35 -76
  153. package/content/references/utilities/date.md +33 -73
  154. package/content/references/utilities/duration.md +85 -0
  155. package/content/references/utilities/index.md +6 -2
  156. package/content/references/utilities/jsx-reference.md +298 -0
  157. package/content/references/utilities/jsx.md +82 -525
  158. package/content/references/utilities/module.md +81 -61
  159. package/content/references/utilities/parse.md +34 -64
  160. package/content/references/utilities/performance.md +33 -58
  161. package/content/references/utilities/promise.md +28 -62
  162. package/content/references/utilities/request.md +58 -218
  163. package/content/references/utilities/retry.md +139 -0
  164. package/content/references/utilities/schema.md +43 -137
  165. package/content/references/utilities/statuses-reference.md +361 -0
  166. package/content/references/utilities/statuses.md +63 -667
  167. package/dist/mcp-server/index.js +0 -0
  168. package/dist/mcp-server/tools/github/list-project-files.tool.d.ts +1 -1
  169. package/dist/mcp-server/tools/github/list-project-files.tool.d.ts.map +1 -1
  170. package/dist/mcp-server/tools/github/list-project-files.tool.js +3 -3
  171. package/dist/mcp-server/tools/github/search-code.tool.js +1 -1
  172. package/dist/mcp-server/tools/github/verify-dependencies.tool.js +1 -1
  173. package/dist/mcp-server/tools/github/view-source-file.tool.js +1 -1
  174. package/package.json +24 -23
@@ -0,0 +1,530 @@
1
+ ---
2
+ title: Inversion (DI) - Full Reference
3
+ description: Complete reference for Container, Binding, MetadataRegistry, decorators, and every error message
4
+ difficulty: intermediate
5
+ ---
6
+
7
+ # Inversion (DI) - Full Reference
8
+
9
+ Exhaustive reference for `Container`, `Binding`, `MetadataRegistry`, the `@inject` decorator, and every type, constant, and error message in `@venizia/ignis-inversion`. For a readable introduction and the most common tasks, start with the [Inversion overview](/extensions/helpers/inversion/).
10
+
11
+ **Files:**
12
+
13
+ - [`packages/inversion/src/modules/container/container.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/container/container.ts) - `Container`
14
+ - [`packages/inversion/src/modules/container/base.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/container/base.ts) - `BaseContainer`
15
+ - [`packages/inversion/src/modules/container/abstract.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/container/abstract.ts) - `AbstractContainer`
16
+ - [`packages/inversion/src/modules/binding/binding.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/binding/binding.ts) - `Binding`
17
+ - [`packages/inversion/src/modules/binding/common/constants.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/binding/common/constants.ts) - `BindingScopes`, `BindingValueTypes`, `BindingKeys`
18
+ - [`packages/inversion/src/modules/binding/common/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/binding/common/types.ts) - `IBinding`, `IProvider`, `isClassProvider`
19
+ - [`packages/inversion/src/modules/metadata/injectors.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/metadata/injectors.ts) - `@inject`
20
+ - [`packages/inversion/src/modules/metadata/common/constants.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/metadata/common/constants.ts) - `MetadataKeys`
21
+ - [`packages/inversion/src/modules/registry/registry.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/registry/registry.ts) - `MetadataRegistry`, `metadataRegistry`
22
+ - [`packages/inversion/src/modules/registry/common/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/registry/common/types.ts) - `IInjectMetadata`, `IPropertyMetadata`
23
+ - [`packages/inversion/src/common/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/common/types.ts) - `TNullable`, `ValueOrPromise`, `TClass`, `TConstValue`, `isClass`
24
+ - [`packages/inversion/src/modules/error/app-error.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/error/app-error.ts) - `ApplicationError`, `getError`, `isApplicationError`
25
+ - [`packages/inversion/src/modules/error/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/error/types.ts) - `TError`, `TErrorDefinition`, `TErrorNormalized`, `IErrorKeyRegistry`
26
+ - [`packages/inversion/src/common/logger.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/common/logger.ts) - `Logger`
27
+
28
+ ## Quick Reference
29
+
30
+ | Item | Value |
31
+ |------|-------|
32
+ | Package | `@venizia/ignis-inversion` |
33
+ | Classes | `Container`, `BaseContainer`, `AbstractContainer`, `Binding`, `MetadataRegistry` |
34
+ | Decorators | `@inject` |
35
+ | Runtimes | Both Bun and Node.js |
36
+ | Build | Dual CJS + ESM |
37
+
38
+ ### Import paths
39
+
40
+ ```typescript
41
+ import {
42
+ Container,
43
+ Binding,
44
+ MetadataRegistry,
45
+ metadataRegistry,
46
+ inject,
47
+ BindingKeys,
48
+ BindingScopes,
49
+ BindingValueTypes,
50
+ MetadataKeys,
51
+ BaseHelper,
52
+ ApplicationError,
53
+ getError,
54
+ isApplicationError,
55
+ MessageCode,
56
+ ErrorScopes,
57
+ Logger,
58
+ isClass,
59
+ isClassProvider,
60
+ } from '@venizia/ignis-inversion';
61
+
62
+ import type {
63
+ TNullable,
64
+ ValueOrPromise,
65
+ ValueOf,
66
+ TClass,
67
+ TConstructor,
68
+ TAbstractConstructor,
69
+ TConstValue,
70
+ TBindingKey,
71
+ TBindingScope,
72
+ TBindingValueType,
73
+ IProvider,
74
+ IBinding,
75
+ IContainer,
76
+ IInjectMetadata,
77
+ IPropertyMetadata,
78
+ IBindingTag,
79
+ } from '@venizia/ignis-inversion';
80
+ ```
81
+
82
+ > [!NOTE]
83
+ > The framework package `@venizia/ignis` re-exports these DI symbols from `@venizia/ignis-inversion`, types included: `Binding`, `BindingKeys`, `BindingScopes`, `BindingValueTypes`, `IProvider`, `isClass`, `isClassProvider`, `TBindingScope`, `TBindingValueType`, `IBindingTag`. It also adds higher-level helpers of its own (`app.controller()`, `app.service()`, etc.).
84
+
85
+ ## Class Hierarchy
86
+
87
+ `Source ->` [`container/abstract.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/container/abstract.ts), [`container/base.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/container/base.ts), [`container/container.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/container/container.ts)
88
+
89
+ ```
90
+ AbstractContainer extends BaseHelper implements IContainer # contract only - every member abstract
91
+ └── BaseContainer # storage: bind/lookup/tags/lifecycle, `instantiate` still abstract
92
+ └── Container # instantiate() = two-phase decorator injection
93
+ ```
94
+
95
+ `AbstractContainer` exists so a container implementation that shares nothing with the shipped storage can start there. One that only wants to vary resolution extends `BaseContainer` instead. `binding/` and `container/` only talk to each other through `IContainer`/`IBinding` - there is no import cycle between the two folders.
96
+
97
+ ## Creating a Container
98
+
99
+ ```typescript
100
+ import { Container } from '@venizia/ignis-inversion';
101
+
102
+ const container = new Container({ scope: 'MyApp' });
103
+ ```
104
+
105
+ `scope` is optional and defaults to `'Container'` (or `'BaseContainer'`/`'AbstractContainer'` for those classes). It is passed through to `BaseHelper` and used for logging/error context only - it has no effect on binding resolution.
106
+
107
+ ## Container
108
+
109
+ `Source ->` [`container/base.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/container/base.ts), [`container/container.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/container/container.ts)
110
+
111
+ | Method | Signature | Description |
112
+ |--------|-----------|--------------|
113
+ | `bind` | `bind<T>(opts: { key: TBindingKey }): Binding<T>` | Create a new `Binding`, register it under `String(key)`, and return it |
114
+ | `get` | `get<T>(opts: { key: TBindingKey \| { namespace, key }, isOptional?: boolean }): T \| undefined` | Resolve a dependency by key. Throws if not found and `isOptional` is falsy |
115
+ | `gets` | `gets<T>(opts: { bindings: Array<{ key, isOptional? }> }): T[]` | Resolve multiple dependencies; every entry is internally re-issued with `isOptional: true` regardless of what was passed |
116
+ | `getBinding` | `getBinding<T>(opts: { key: TBindingKey \| { namespace, key } }): Binding<T> \| undefined` | Retrieve the raw `Binding` without resolving it |
117
+ | `set` | `set<T>(opts: { binding: Binding<T> }): void` | Register an externally created `Binding` under its own `.key` |
118
+ | `isBound` | `isBound(opts: { key: TBindingKey }): boolean` | Check whether a key is registered |
119
+ | `unbind` | `unbind(opts: { key: TBindingKey }): boolean` | Remove a binding; returns `true` if one was removed |
120
+ | `resolve` | `resolve<T>(cls: TClass<T>): T` | Alias for `instantiate` |
121
+ | `instantiate` | `instantiate<T>(cls: TClass<T>): T` | Build an instance with full DI (constructor + property injection), see below |
122
+ | `findByTag` | `findByTag<T>(opts: { tag: string, exclude?: string[] \| Set<string> }): Binding<T>[]` | Find every binding with a matching tag, optionally excluding keys |
123
+ | `clear` | `clear(): void` | Clear every binding's singleton cache; bindings themselves remain registered |
124
+ | `reset` | `reset(): void` | Remove all bindings entirely |
125
+ | `getMetadataRegistry` | `getMetadataRegistry(): MetadataRegistry` | Return the shared `metadataRegistry` singleton |
126
+
127
+ All keys passed to `bind`, `isBound`, and `unbind` are normalized with `String(key)` before being used as the `Map` key. A `Symbol` key resolves to its `.toString()` form (`'Symbol(...)'`), so a `symbol` and the equivalent string are distinct entries.
128
+
129
+ ### `instantiate()` - two-phase algorithm
130
+
131
+ ```typescript
132
+ override instantiate<T>(cls: TClass<T>): T
133
+ ```
134
+
135
+ **Phase 1 - constructor injection.** Reads `registry.getInjectMetadata({ target: cls })`, which returns the index-keyed `IInjectMetadata[]` array built by `@inject`. For every index in that array:
136
+
137
+ - If the slot is empty (an undecorated parameter left a hole), throws `[ClassName] Constructor parameter N has no @inject | Every parameter of a container-instantiated class must be decorated - the container cannot supply an undecorated one`.
138
+ - Otherwise resolves `this.get({ key: meta.key, isOptional: meta.isOptional ?? false })` and places it at `args[meta.index]`.
139
+
140
+ The array is already index-keyed (`setInjectMetadata` writes to `injects[index]`) - there is no sort step. Once all arguments are resolved, `new cls(...args)` builds the instance.
141
+
142
+ **Phase 2 - property injection.** Reads `registry.getPropertiesMetadata({ target: instance })`. If there is none, returns the instance as-is.
143
+
144
+ Otherwise, for each `[propertyKey, metadata]` entry, resolves `this.get({ key: metadata.bindingKey, isOptional: metadata.isOptional ?? false })` and assigns it to `instance[propertyKey]`.
145
+
146
+ `@inject({ key, isOptional: true })` on a **property** behaves exactly like on a constructor parameter: an unbound key resolves to `undefined` instead of throwing. A required property (`isOptional` omitted or `false`) still throws when its key is unbound.
147
+
148
+ ### Key formats
149
+
150
+ `get`, `getBinding`, and `gets` accept three key shapes:
151
+
152
+ ```typescript
153
+ container.get<UserService>({ key: 'services.UserService' });
154
+ container.get<UserService>({ key: Symbol.for('services.UserService') });
155
+ container.get<UserService>({ key: { namespace: 'services', key: 'UserService' } });
156
+ ```
157
+
158
+ `getBinding` throws `[getBinding] Invalid binding key type | ...` if `opts.key` is not a `string`, `symbol`, or `{ namespace, key }` object.
159
+
160
+ ### `gets()` behavior
161
+
162
+ ```typescript
163
+ const [svcA, svcB] = container.gets<[ServiceA, ServiceB]>({
164
+ bindings: [
165
+ { key: 'services.ServiceA' },
166
+ { key: 'services.ServiceB', isOptional: true },
167
+ ],
168
+ });
169
+ ```
170
+
171
+ Internally maps each entry through `this.get({ ...opt, isOptional: true })`. Regardless of what `isOptional` was set on the entry, `gets()` always resolves with `isOptional: true` - anything unbound returns `undefined` instead of throwing.
172
+
173
+ ## Binding
174
+
175
+ `Source ->` [`binding/binding.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/binding/binding.ts)
176
+
177
+ | Method | Signature | Description |
178
+ |--------|-----------|--------------|
179
+ | `toClass` | `toClass(value: TClass<T>): this` | Container instantiates `value` with full DI when resolved |
180
+ | `toValue` | `toValue(value: T): this` | Returns `value` directly, no instantiation |
181
+ | `toProvider` | `toProvider(value: ((container) => T) \| TClass<IProvider<T>>): this` | Factory function, or a class whose prototype has a `value()` method |
182
+ | `setScope` | `setScope(scope: TBindingScope): this` | `'singleton'` or `'transient'` (default) |
183
+ | `setTags` | `setTags(...tags: string[]): this` | Adds tags to the internal `Set<string>` |
184
+ | `hasTag` | `hasTag(tag: string): boolean` | Check for a specific tag |
185
+ | `getTags` | `getTags(): string[]` | All tags as an array |
186
+ | `getScope` | `getScope(): TBindingScope` | Current scope |
187
+ | `getValue` | `getValue(container?: IContainer): T` | Resolve the bound value, respecting scope caching |
188
+ | `getBindingMeta` | `getBindingMeta(opts: { type: TBindingValueType }): TBindingResolverValue<T>` | Raw resolver value; throws if `type` does not match the actual resolver |
189
+ | `clearCache` | `clearCache(): void` | Clears this binding's singleton cache (no-op if nothing cached) |
190
+ | `bind` (static) | `static bind<T>(opts: { key: string }): Binding<T>` | Create a `Binding` outside a container |
191
+
192
+ ### Constructor and namespace auto-tagging
193
+
194
+ ```typescript
195
+ constructor(opts: { key: string })
196
+ ```
197
+
198
+ Splits `key` on `.`. If there is more than one segment, the first segment is auto-added as a tag via `setTags()`. `'services.UserService'` auto-tags `'services'`. A key with no `.` gets no automatic tag.
199
+
200
+ ### `getValue()` resolution by type
201
+
202
+ | Resolver type | Behavior | Throws when |
203
+ |----------------|----------|--------------|
204
+ | `VALUE` | Returns the stored value directly | Never |
205
+ | `PROVIDER` (plain function) | Calls `provider(container)` | No `container` argument was passed - `[getValue] Invalid context/container to get provider value` |
206
+ | `PROVIDER` (class, matched via `isClassProvider`) | `container.instantiate()`s the class, then calls `.value(container)` on the instance | Same as above |
207
+ | `CLASS` | `container.instantiate(this.resolver.value)` | No `container` argument was passed - `[getValue] Invalid context/container to instantiate class` |
208
+
209
+ `isClassProvider` matches a class whose prototype has a `value()` method - see [Class-based provider](#class-based-provider) below.
210
+
211
+ If `bindScope` is `SINGLETON`, the resolved instance is cached on `this.cached`. Every subsequent call returns it directly without re-invoking the resolver - caching is per-`Binding` instance, not per-container.
212
+
213
+ ### Class-based provider
214
+
215
+ ```typescript
216
+ import { IProvider, Container } from '@venizia/ignis-inversion';
217
+
218
+ class DatabaseConnectionProvider implements IProvider<DatabaseConnection> {
219
+ value(container: Container): DatabaseConnection {
220
+ const config = container.get<Config>({ key: 'config.database' });
221
+ return new DatabaseConnection(config);
222
+ }
223
+ }
224
+
225
+ container.bind<DatabaseConnection>({ key: 'db.connection' }).toProvider(DatabaseConnectionProvider);
226
+ ```
227
+
228
+ `isClassProvider` detects this shape at runtime: `typeof target === 'function' && target.prototype && typeof target.prototype.value === 'function'`.
229
+
230
+ ### Static factory
231
+
232
+ ```typescript
233
+ import { Binding, BindingScopes } from '@venizia/ignis-inversion';
234
+
235
+ const binding = Binding.bind<IHealthCheckOptions>({ key: 'options.healthCheck' })
236
+ .toValue({ restOptions: { path: '/health' } });
237
+
238
+ container.set({ binding }); // registers under binding.key
239
+ ```
240
+
241
+ ## MetadataRegistry
242
+
243
+ `Source ->` [`registry/registry.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/registry/registry.ts)
244
+
245
+ Singleton (`metadataRegistry`) backing `@inject`, built entirely on `reflect-metadata`'s `Reflect.defineMetadata`/`getMetadata`/`hasMetadata`/`deleteMetadata`. You typically interact with it only through `container.getMetadataRegistry()` or the decorators.
246
+
247
+ | Method | Signature | Description |
248
+ |--------|-----------|--------------|
249
+ | `define` | `define<Target, Value>(opts: { target, key: TBindingKey, value: Value }): void` | Store arbitrary metadata on a target |
250
+ | `get` | `get<Target, Value>(opts: { target, key: TBindingKey }): Value \| undefined` | Retrieve metadata by key |
251
+ | `has` | `has<Target>(opts: { target, key: TBindingKey }): boolean` | Check if metadata exists |
252
+ | `delete` | `delete<Target>(opts: { target, key: TBindingKey }): boolean` | Remove metadata by key |
253
+ | `getKeys` | `getKeys<Target>(opts: { target }): TBindingKey[]` | List all metadata keys (`string`/`symbol` only) on a target |
254
+ | `getMethodNames` | `getMethodNames<T>(opts: { target: TClass<T> }): string[]` | Non-constructor function-valued own property names on the prototype |
255
+ | `clearMetadata` | `clearMetadata<T>(opts: { target }): void` | Delete every metadata key on a target |
256
+ | `setInjectMetadata` | `setInjectMetadata<T>(opts: { target, index: number, metadata: IInjectMetadata }): void` | Write constructor `@inject` metadata at parameter `index` into the `MetadataKeys.INJECT` array |
257
+ | `getInjectMetadata` | `getInjectMetadata<T>(opts: { target }): IInjectMetadata[] \| undefined` | Read the constructor injection array |
258
+ | `setPropertyMetadata` | `setPropertyMetadata<T>(opts: { target, propertyName, metadata: IPropertyMetadata }): void` | Write property `@inject` metadata into a `Map` keyed by property name, stored on `target.constructor` |
259
+ | `getPropertiesMetadata` | `getPropertiesMetadata<T>(opts: { target }): Map<string \| symbol, IPropertyMetadata> \| undefined` | Read the full property metadata map |
260
+ | `getPropertyMetadata` | `getPropertyMetadata<T>(opts: { target, propertyName }): IPropertyMetadata \| undefined` | Read metadata for one property |
261
+
262
+ ```typescript
263
+ import { MetadataKeys, metadataRegistry } from '@venizia/ignis-inversion';
264
+
265
+ MetadataKeys.PROPERTIES; // Symbol.for('ignis:properties')
266
+ MetadataKeys.INJECT; // Symbol.for('ignis:inject')
267
+
268
+ metadataRegistry.define({ target: myObj, key: 'custom:flag', value: true });
269
+ metadataRegistry.get({ target: myObj, key: 'custom:flag' }); // true
270
+ metadataRegistry.has({ target: myObj, key: 'custom:flag' }); // true
271
+ metadataRegistry.delete({ target: myObj, key: 'custom:flag' }); // true
272
+ ```
273
+
274
+ ### MetadataRegistry types
275
+
276
+ ```typescript
277
+ interface IInjectMetadata {
278
+ key: TBindingKey;
279
+ index: number;
280
+ isOptional?: boolean;
281
+ }
282
+
283
+ interface IPropertyMetadata {
284
+ bindingKey: TBindingKey;
285
+ isOptional?: boolean;
286
+ }
287
+ ```
288
+
289
+ ## Decorators
290
+
291
+ `Source ->` [`metadata/injectors.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/metadata/injectors.ts)
292
+
293
+ ### `@inject`
294
+
295
+ ```typescript
296
+ inject(opts: { key: TBindingKey; isOptional?: boolean; registry?: MetadataRegistry }): PropertyDecorator | ParameterDecorator
297
+ ```
298
+
299
+ Dispatches on how the decorator was invoked:
300
+
301
+ | Applied to | Detection | Stored via |
302
+ |------------|-----------|------------|
303
+ | Constructor parameter | `parameterIndex` is a `number` | `registry.setInjectMetadata({ target, index: parameterIndex, metadata: { key, index: parameterIndex, isOptional } })` |
304
+ | Class property | `propertyName !== undefined` | `registry.setPropertyMetadata({ target, propertyName, metadata: { bindingKey: key, isOptional } })` |
305
+ | Anything else | neither condition matches | Throws `@inject decorator can only be used on class properties or constructor parameters` |
306
+
307
+ `isOptional` defaults to `false` in both branches. Pass a custom `registry` to target a non-default `MetadataRegistry` instance (rare - almost always omitted, using the shared `metadataRegistry`).
308
+
309
+ ```typescript
310
+ class UserService {
311
+ constructor(
312
+ @inject({ key: 'repositories.UserRepository' }) private userRepository: UserRepository,
313
+ @inject({ key: 'services.Logger', isOptional: true }) private logger?: Logger,
314
+ ) {}
315
+
316
+ @inject({ key: 'config.retryCount' })
317
+ private retryCount: number;
318
+ }
319
+ ```
320
+
321
+ ## Namespaces and Tags
322
+
323
+ ```typescript
324
+ import { BindingKeys } from '@venizia/ignis-inversion';
325
+
326
+ BindingKeys.build({ namespace: 'services', key: 'UserService' });
327
+ // => 'services.UserService'
328
+
329
+ BindingKeys.build({ namespace: '', key: 'UserService' });
330
+ // => 'UserService' (empty namespace segment is dropped)
331
+
332
+ BindingKeys.build({ namespace: 'services', key: '' });
333
+ // throws: [BindingKeys][build] Invalid key to build | key:
334
+ ```
335
+
336
+ `key` is required and must be non-empty. `namespace` is optional - it's silently omitted from the joined string when empty.
337
+
338
+ ```typescript
339
+ container.bind({ key: 'workers.EmailWorker' }).toClass(EmailWorker).setTags('background', 'email');
340
+ // tags: ['workers', 'background', 'email']
341
+
342
+ const serviceBindings = container.findByTag({ tag: 'services' });
343
+ const filtered = container.findByTag({ tag: 'services', exclude: ['services.InternalService'] });
344
+ ```
345
+
346
+ ## Utilities
347
+
348
+ ### ApplicationError and getError
349
+
350
+ `Source ->` [`modules/error/app-error.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/modules/error/app-error.ts)
351
+
352
+ ```typescript
353
+ class ApplicationError extends Error {
354
+ statusCode: number;
355
+ normalized: { text: string; code: string; args: Record<string, unknown> };
356
+ extra?: Record<string, unknown>;
357
+ }
358
+
359
+ getError(opts: TError): ApplicationError; // factory function
360
+ ```
361
+
362
+ `opts.message` accepts two shapes: the historical string (paired with sibling `messageCode?`/`messageArgs?`), or an object mirroring `normalized` - `{ text, code?, args? }`. Both resolve to the same `normalized`.
363
+
364
+ `messageCode`/`messageArgs` are lowest precedence - `message.code`/`message.args`, or a catalogued definition's own, win when both are present. There is no flat `error.messageCode`. `extra` never mirrors `messageArgs`. `normalized.args` is always populated (`{}` when empty).
365
+
366
+ The catalogued form (`{ error: TErrorDefinition }`) takes `message` as a **partial** override. `{ message: { args } }` amends just the args and keeps the definition's `text`/`code`. `error` is refused on the free-form branch (`error?: never`) - wrap a caught failure with `cause` instead.
367
+
368
+ `ApplicationError`'s constructor defaults `statusCode` to `400` when omitted, and moves any property it does not model into `this.extra`. The error RESPONSE schema (`ErrorSchema`, for OpenAPI) lives in `@venizia/ignis-helpers`, not here. It needs `@hono/zod-openapi`, which inversion must not depend on - inversion ships to browsers.
369
+
370
+ ```typescript
371
+ throw getError({ message: 'Something failed', statusCode: 500, messageCode: 'ERR_INTERNAL' });
372
+ throw new ApplicationError({ message: 'Not found', statusCode: 404 });
373
+ throw new ApplicationError({ message: { text: 'Not found', code: 'core.user.not_found' }, statusCode: 404 });
374
+
375
+ // The code and args are read off `normalized`, never off the error directly.
376
+ error.normalized.code; // 'err_internal'
377
+ ```
378
+
379
+ See the [Error reference](/extensions/helpers/error/) for the full input shape, precedence rules, and the catalogued (`TErrorDefinition`) pattern.
380
+
381
+ ### Logger
382
+
383
+ `Source ->` [`common/logger.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/common/logger.ts)
384
+
385
+ A minimal `console`-backed static logger, independent of `@venizia/ignis-helpers`' `Logger`/`LoggerFactory` - this one exists so the inversion package has zero dependency on the logging package.
386
+
387
+ ```typescript
388
+ Logger.info('Server started on port %d', 3000); // console.log('[INFO] ...')
389
+ Logger.warn('Deprecation warning'); // console.warn('[WARN] ...')
390
+ Logger.error('Connection failed: %s', err.message); // console.error('[ERROR] ...')
391
+ Logger.debug('Resolved binding: %s', key); // console.log('[DEBUG] ...') only if process.env.DEBUG is set
392
+ ```
393
+
394
+ ### Type guards and shared types
395
+
396
+ `Source ->` [`common/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/inversion/src/common/types.ts)
397
+
398
+ ```typescript
399
+ type TNullable<T> = T | undefined | null;
400
+ type ValueOrPromise<T> = T | Promise<T>;
401
+ type ValueOf<T> = T[keyof T];
402
+ type TConstructor<T> = new (...args: any[]) => T;
403
+ type TAbstractConstructor<T> = abstract new (...args: any[]) => T;
404
+ type TClass<T> = TConstructor<T> & { [property: string]: any };
405
+ type TConstValue<T extends TClass<any>> = Extract<ValueOf<T>, string | number>;
406
+ type TBindingKey = string | symbol;
407
+
408
+ interface IBindingTag {
409
+ [name: string]: any;
410
+ }
411
+
412
+ function isClass<T>(target: any): target is TClass<T>;
413
+ ```
414
+
415
+ `isClass` tests `typeof target === 'function' && target.prototype !== undefined` plus a regex match on the function's stringified source (`/^class[\s{]/`). It relies on the class being emitted as an ES2024 `class`, not transpiled down to an ES5 constructor function.
416
+
417
+ ```typescript
418
+ interface IProvider<T> {
419
+ value(container: Container): T;
420
+ }
421
+
422
+ function isClassProvider<T>(target: any): target is TClass<IProvider<T>>;
423
+ ```
424
+
425
+ ## Constants
426
+
427
+ | Constant | Values | Description |
428
+ |----------|--------|--------------|
429
+ | `BindingScopes.SINGLETON` | `'singleton'` | Cached after first resolution |
430
+ | `BindingScopes.TRANSIENT` | `'transient'` | New instance each resolution |
431
+ | `BindingValueTypes.CLASS` | `'class'` | Container instantiates with DI |
432
+ | `BindingValueTypes.VALUE` | `'value'` | Direct value return |
433
+ | `BindingValueTypes.PROVIDER` | `'provider'` | Factory function or `IProvider` class |
434
+ | `MetadataKeys.PROPERTIES` | `Symbol.for('ignis:properties')` | Property injection metadata key |
435
+ | `MetadataKeys.INJECT` | `Symbol.for('ignis:inject')` | Constructor injection metadata key |
436
+
437
+ ## Troubleshooting
438
+
439
+ ### "Binding key: X is not bounded in context!"
440
+
441
+ **Cause:** The dependency was never registered with the container, or the key does not match exactly.
442
+
443
+ **Fix:**
444
+ 1. Verify the binding exists: `container.isBound({ key: 'services.UserService' })`.
445
+ 2. Check for typos between `@inject({ key: '...' })` and the key used in `container.bind({ key: '...' })`.
446
+ 3. If the dependency is genuinely optional, add `isOptional: true` to the `@inject` call - constructor parameter or property, both work - or use `container.get({ key: '...', isOptional: true })`.
447
+
448
+ ### "[getValue] Invalid context/container to instantiate class"
449
+
450
+ **Cause:** A `Binding` configured with `toClass()` was resolved by calling `binding.getValue()` directly, without a `Container` argument.
451
+
452
+ **Fix:** Resolve class bindings through the container - `container.get({ key })` - rather than calling `binding.getValue()` with no arguments.
453
+
454
+ ### "[getValue] Invalid context/container to get provider value"
455
+
456
+ **Cause:** A `Binding` configured with `toProvider()` was resolved without a `Container` argument.
457
+
458
+ **Fix:** Same as above - always resolve through `container.get({ key })`.
459
+
460
+ ### "[getBindingMeta] Invalid resolver type"
461
+
462
+ **Cause:** `getBindingMeta({ type })` was called with a type that does not match the binding's actual resolver (e.g. `'class'` on a value binding).
463
+
464
+ **Fix:** Match `type` to how the binding was created: `toClass()` -> `'class'`, `toValue()` -> `'value'`, `toProvider()` -> `'provider'`.
465
+
466
+ ### "[getBinding] Invalid binding key type"
467
+
468
+ **Cause:** The key passed to `getBinding()` is not a `string`, `symbol`, or `{ namespace, key }` object.
469
+
470
+ **Fix:** Use one of the three supported key formats.
471
+
472
+ ### "[BindingKeys][build] Invalid key to build"
473
+
474
+ **Cause:** `BindingKeys.build()` was called with an empty `key`.
475
+
476
+ **Fix:** Provide a non-empty `key`: `BindingKeys.build({ namespace: 'services', key: 'UserService' })`.
477
+
478
+ ### "[ClassName] Constructor parameter N has no @inject"
479
+
480
+ **Cause:** A container-instantiated class has a constructor mixing decorated and undecorated parameters. `@inject` stores metadata at the parameter's index, so an undecorated parameter leaves a hole in that array. There is no channel through which the container could supply it anyway.
481
+
482
+ **Fix:** Decorate every constructor parameter with `@inject`. There is no partial-injection escape hatch. If a value doesn't come from the container (e.g. a plain `scope: string`), choose one:
483
+
484
+ - Pass it through a factory/provider instead of a bare constructor parameter.
485
+ - Have the subclass forward it via its own `@inject`-decorated parameter.
486
+
487
+ ### "@inject decorator can only be used on class properties or constructor parameters"
488
+
489
+ **Cause:** `@inject` was applied to something other than a class property or constructor parameter.
490
+
491
+ **Fix:** Only use `@inject` on constructor parameters or class properties.
492
+
493
+ ### Property injection never runs
494
+
495
+ **Cause:** The class was instantiated with `new MyClass()` directly instead of through the container. Only `container.resolve()`/`instantiate()` reads `@inject` metadata and populates properties. A plain `new` leaves them at whatever their field initializer set - `undefined` if none.
496
+
497
+ **Fix:** Always use `container.resolve(MyClass)` or `container.instantiate(MyClass)` to create instances that use property injection.
498
+
499
+ ### "getInjectMetadata returns undefined"
500
+
501
+ **Cause:** `reflect-metadata` was not imported before decorators were evaluated, or `experimentalDecorators`/`emitDecoratorMetadata` are not enabled in `tsconfig.json`.
502
+
503
+ **Fix:**
504
+ 1. Ensure `import 'reflect-metadata'` runs before any decorated class is evaluated - `@venizia/ignis-inversion`'s entry point already does this, so importing anything from the package is enough.
505
+ 2. Verify `tsconfig.json` includes:
506
+ ```json
507
+ {
508
+ "compilerOptions": {
509
+ "experimentalDecorators": true,
510
+ "emitDecoratorMetadata": true
511
+ }
512
+ }
513
+ ```
514
+
515
+ ### Singleton returns a stale instance after rebinding
516
+
517
+ **Cause:** Singleton caching is per-`Binding` object. Holding a direct reference to an old `Binding` (e.g. from `getBinding()`) keeps its cache independent of any new binding registered under the same key.
518
+
519
+ **Fix:**
520
+ 1. Always resolve via `container.get()` rather than caching `Binding` references.
521
+ 2. Call `container.clear()` to clear every binding's singleton cache without removing registrations.
522
+ 3. Call `container.reset()` to remove all bindings entirely.
523
+
524
+ ## See also
525
+
526
+ - [Inversion overview](/extensions/helpers/inversion/) - introduction and the most common tasks
527
+ - [Dependency Injection Guide](/guides/core-concepts/dependency-injection) - DI fundamentals in the framework layer
528
+ - [Application](/guides/core-concepts/application/) - `Application` extends `Container`
529
+ - [Dependency Injection API](/references/base/dependency-injection) - the framework-layer DI reference
530
+ - [Architectural Patterns](/best-practices/architectural-patterns) - DI patterns
@@ -1,3 +1,9 @@
1
+ ---
2
+ title: Kafka Admin
3
+ description: KafkaAdminHelper - topic, group, offset, ACL, and quota management
4
+ difficulty: intermediate
5
+ ---
6
+
1
7
  # Admin
2
8
 
3
9
  The `KafkaAdminHelper` wraps `@platformatic/kafka`'s `Admin` with health tracking, graceful shutdown, and broker event callbacks. Use `getAdmin()` to access the full Admin API directly.
@@ -7,7 +13,7 @@ class KafkaAdminHelper extends BaseKafkaHelper<Admin>
7
13
  ```
8
14
 
9
15
  > [!NOTE]
10
- > `KafkaAdminHelper` has **no generic type parameters** -- the Admin client does not deal with serialized messages.
16
+ > `KafkaAdminHelper` has **no generic type parameters** - the Admin client does not deal with serialized messages.
11
17
 
12
18
  ## Helper API
13
19
 
@@ -18,6 +24,7 @@ class KafkaAdminHelper extends BaseKafkaHelper<Admin>
18
24
  | `isHealthy()` | `(): boolean` | `true` when broker connected |
19
25
  | `isReady()` | `(): boolean` | Same as `isHealthy()` |
20
26
  | `getHealthStatus()` | `(): TKafkaHealthStatus` | `'connected'` \| `'disconnected'` \| `'unknown'` |
27
+ | `getConnectedBrokerCount()` | `(): number` | Number of currently connected brokers |
21
28
  | `close(opts?)` | `(opts?: { isForce?: boolean }): Promise<void>` | Close the admin connection (default: graceful) |
22
29
 
23
30
  ## IKafkaAdminOptions
@@ -31,7 +38,7 @@ interface IKafkaAdminOptions extends IKafkaConnectionOptions {
31
38
  }
32
39
  ```
33
40
 
34
- Plus all [Connection Options](./#connection-options).
41
+ Plus the shared [Connection & Authentication](./producer#connection--authentication) options (`bootstrapBrokers`, `clientId`, `retries`, `sasl`, `tls`, ...), documented once on the Producer page.
35
42
 
36
43
  ## Basic Example
37
44
 
@@ -65,7 +72,7 @@ await helper.close({ isForce: true });
65
72
 
66
73
  ## Graceful Shutdown
67
74
 
68
- `close()` uses the base `closeClient()` (which calls `this.client.close()`) with a graceful timeout. If the graceful close exceeds `shutdownTimeout` (default 30s), it automatically force-closes. After `close()`, `healthStatus` is set to `'disconnected'`.
75
+ `close()` uses the base `closeClient()`, wrapped in a graceful timeout. `closeClient()` calls `this.client.close()` directly. If the graceful close exceeds `shutdownTimeout` (default 30s), it automatically force-closes. After `close()`, `healthStatus` becomes `'disconnected'`.
69
76
 
70
77
  ```typescript
71
78
  // Graceful (recommended)
@@ -188,3 +195,16 @@ await admin.alterConsumerGroupOffsets({
188
195
  | Method | Signature | Description |
189
196
  |--------|-----------|-------------|
190
197
  | `describeLogDirs(opts)` | `(opts: { topics }): Promise<BrokerLogDirDescription[]>` | Describe broker log directories |
198
+
199
+ ## See also
200
+
201
+ - [Kafka Overview](./) - the four helpers, shared health/close API, and the compile-binary caveat
202
+ - [Producer](./producer) - the shared Connection & Authentication options
203
+ - [Consumer](./consumer) - `groupInstanceId`, rebalance behavior, and lag monitoring for the groups this page manages
204
+ - [Examples & Troubleshooting](./examples) - a full topic-setup script and IoC wiring
205
+
206
+ **Files:**
207
+
208
+ - [`packages/helpers/src/modules/queue/kafka/admin.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/admin.ts) - `KafkaAdminHelper`
209
+ - [`packages/helpers/src/modules/queue/kafka/base.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/base.ts) - `BaseKafkaHelper`, shared health tracking and shutdown
210
+ - [`packages/helpers/src/modules/queue/kafka/common/types.ts`](https://github.com/VENIZIA-AI/ignis/blob/main/packages/helpers/src/modules/queue/kafka/common/types.ts) - `IKafkaAdminOptions`