@bymax-one/nest-queue 1.0.3 → 1.0.4

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/CHANGELOG.md CHANGED
@@ -7,6 +7,61 @@ versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ---
9
9
 
10
+ ## [1.0.4] — 2026-08-01
11
+
12
+ ### Fixed
13
+
14
+ - **`BymaxQueueModuleAsyncOptions.useFactory` rejected the factory this library
15
+ documents.** It was declared `(...args: unknown[]) => …`, and a parameter typed
16
+ `unknown` accepts no narrower parameter under `strictFunctionTypes`. So the
17
+ shape shown in the README and in `BymaxQueueModule`'s own `@example`:
18
+
19
+ ```ts
20
+ useFactory: (client: Redis) => ({ connection: { client } })
21
+ ```
22
+
23
+ failed to typecheck **against the exported interface**:
24
+
25
+ ```
26
+ TS2322: Type '(client: Redis) => …' is not assignable to
27
+ type '(...args: unknown[]) => …'
28
+ ```
29
+
30
+ Scope, precisely: `forRootAsync` is typed by NestJS's `ASYNC_OPTIONS_TYPE`, not
31
+ by this interface, so passing the object **inline** always compiled. Only a
32
+ consumer who annotated it — extracting the options into a
33
+ `const opts: BymaxQueueModuleAsyncOptions = { … }` — hit the error. The
34
+ interface was stricter than the module it describes.
35
+
36
+ It is now declared with **method syntax**. `strictFunctionTypes` makes
37
+ parameters contravariant for function-typed _properties_ but leaves method
38
+ parameters bivariant, so the interface accepts a factory that names its
39
+ injected types. This **widens** what is accepted: every factory that compiled
40
+ before still does, the variadic `(...args: unknown[])` form included. Nothing
41
+ needs changing in consumer code.
42
+
43
+ Method syntax rather than a looser parameter type, because the factory has to
44
+ stay **callable**: NestJS invokes it with the values `inject` resolves, and a
45
+ consumer may call it directly in a unit test. A `never[]` rest parameter would
46
+ have bought the same assignability and silently cost that —
47
+ `options.useFactory(client)` fails with `TS2345: Argument of type 'Redis' is
48
+ not assignable to parameter of type 'never'`.
49
+
50
+ Pinned by seven cases in `test/types/public-api.test-d.ts` — typed parameter,
51
+ async, several parameters, zero parameters, the pre-1.0.4 variadic form, and
52
+ two for callability — where `useFactory` was previously pinned by nothing,
53
+ which is why this went unnoticed. Red-checked against **both** rejected
54
+ signatures: the original property form fails the assignability cases, and
55
+ `never[]` fails the callability ones.
56
+
57
+ No runtime change, verified rather than asserted: diffed against the published
58
+ `1.0.3` tarball, all four emitted runtime files (`server` and `shared`, `.mjs`
59
+ and `.cjs`) are byte-identical, and only `dist/server/index.d.ts` / `.d.cts`
60
+ differ. The altered source declares types only, so it produces no Stryker
61
+ mutants and the 99.06% score stands.
62
+
63
+ ---
64
+
10
65
  ## [1.0.3] — 2026-08-01
11
66
 
12
67
  Documentation only. `dist/` is byte-identical to `1.0.2` — verified by unpacking
@@ -97,8 +97,29 @@ interface BymaxQueueOptionsFactory {
97
97
  }
98
98
  /** Asynchronous configuration mirroring the NestJS async dynamic-module pattern. */
99
99
  interface BymaxQueueModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
100
- /** Factory returning the module options. */
101
- useFactory?: (...args: unknown[]) => Promise<BymaxQueueModuleOptions> | BymaxQueueModuleOptions;
100
+ /**
101
+ * Factory returning the module options. Its parameters are whatever `inject`
102
+ * resolves to, so declare them with the types you expect:
103
+ *
104
+ * ```ts
105
+ * useFactory: (client: Redis) => ({ connection: { client } })
106
+ * ```
107
+ *
108
+ * Declared with **method syntax** on purpose. `strictFunctionTypes` makes
109
+ * parameters contravariant for function-typed *properties* but leaves method
110
+ * parameters bivariant, so this accepts a factory that names its injected
111
+ * types — which a property typed `(...args: unknown[]) => …` rejects, since
112
+ * `unknown` is assignable from no narrower parameter. That rejection is what
113
+ * made the form above fail against this interface while compiling when passed
114
+ * inline to `forRootAsync`.
115
+ *
116
+ * Bivariance is the right trade here rather than a looser parameter type:
117
+ * NestJS resolves these arguments from `inject` at runtime, so no signature
118
+ * can make them statically safe, and method syntax keeps the factory
119
+ * **callable** — `options.useFactory(client)` typechecks, which a
120
+ * `never[]` rest parameter would have broken.
121
+ */
122
+ useFactory?(...args: unknown[]): Promise<BymaxQueueModuleOptions> | BymaxQueueModuleOptions;
102
123
  /** Class implementing the options factory. */
103
124
  useClass?: Type<BymaxQueueOptionsFactory>;
104
125
  /** Existing provider implementing the options factory. */
@@ -97,8 +97,29 @@ interface BymaxQueueOptionsFactory {
97
97
  }
98
98
  /** Asynchronous configuration mirroring the NestJS async dynamic-module pattern. */
99
99
  interface BymaxQueueModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
100
- /** Factory returning the module options. */
101
- useFactory?: (...args: unknown[]) => Promise<BymaxQueueModuleOptions> | BymaxQueueModuleOptions;
100
+ /**
101
+ * Factory returning the module options. Its parameters are whatever `inject`
102
+ * resolves to, so declare them with the types you expect:
103
+ *
104
+ * ```ts
105
+ * useFactory: (client: Redis) => ({ connection: { client } })
106
+ * ```
107
+ *
108
+ * Declared with **method syntax** on purpose. `strictFunctionTypes` makes
109
+ * parameters contravariant for function-typed *properties* but leaves method
110
+ * parameters bivariant, so this accepts a factory that names its injected
111
+ * types — which a property typed `(...args: unknown[]) => …` rejects, since
112
+ * `unknown` is assignable from no narrower parameter. That rejection is what
113
+ * made the form above fail against this interface while compiling when passed
114
+ * inline to `forRootAsync`.
115
+ *
116
+ * Bivariance is the right trade here rather than a looser parameter type:
117
+ * NestJS resolves these arguments from `inject` at runtime, so no signature
118
+ * can make them statically safe, and method syntax keeps the factory
119
+ * **callable** — `options.useFactory(client)` typechecks, which a
120
+ * `never[]` rest parameter would have broken.
121
+ */
122
+ useFactory?(...args: unknown[]): Promise<BymaxQueueModuleOptions> | BymaxQueueModuleOptions;
102
123
  /** Class implementing the options factory. */
103
124
  useClass?: Type<BymaxQueueOptionsFactory>;
104
125
  /** Existing provider implementing the options factory. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bymax-one/nest-queue",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "NestJS dynamic module wrapping BullMQ — typed jobs, flows, job schedulers, deduplication, OpenTelemetry, graceful shutdown",
5
5
  "author": "Bymax One <support@bymax.one>",
6
6
  "license": "MIT",