@codefast/di 0.6.1 → 0.6.2

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
@@ -1,5 +1,31 @@
1
1
  # @codefast/di
2
2
 
3
+ ## 0.6.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#732](https://github.com/codefastlabs/codefast/pull/732) [`83704d9`](https://github.com/codefastlabs/codefast/commit/83704d96435650946f482f1236ef6633ec19d973) Thanks [@thevuong](https://github.com/thevuong)! - fix(di): reject a deps array longer than the constructor at compile time
8
+
9
+ The deps-checking changeset closed three of the four `@injectable` mismatches and documented the fourth as the one
10
+ TypeScript's arity rules let through: a class taking fewer parameters than `deps` declares satisfies a constructor type
11
+ taking more, so the surplus dependency compiled, resolved, and was discarded — a latent wiring bug nothing reported. The
12
+ deps overload now infers the class and requires `Deps["length"]` to be an arity the constructor declares, so the surplus
13
+ is a compile error at the decorator.
14
+
15
+ Exactly the arities the class admits stay legal: an optional trailing parameter contributes every length it declares
16
+ (the check is against the union), and a rest parameter admits any list. `@injectable()` and `@injectable([])` keep their
17
+ looser overload for classes that inject through accessors. The rejection and both admissions are pinned in
18
+ `tests/types/injection-contract.test.ts` beside the three mismatches already there.
19
+
20
+ The check only binds where the compiler knows the length: a deps **array** — built at runtime, length `number` — skips
21
+ it, which is also the deliberate spelling for declaring more dependencies than the constructor takes (the dependency
22
+ graph's edge declarations do exactly this). The first draft enforced arity on arrays too and was corrected by its own
23
+ first run: it rejected a legitimate mapped-token deps list and the intentional declare-more-than-you-take shape in the
24
+ benchmark suite.
25
+
26
+ A literal deps tuple that compiled against the old signature only did so by carrying a dependency the class could never
27
+ receive — fixing the declaration is deleting the surplus entry.
28
+
3
29
  ## 0.6.1
4
30
 
5
31
  ### Patch Changes
@@ -38,12 +38,15 @@ type InjectedParameters<Deps extends ReadonlyArray<InjectableDependency>> = {
38
38
  export declare function injectable(): (target: unknown, context: ClassDecoratorContext) => void;
39
39
  /**
40
40
  * @remarks Declaring dependencies constrains the class: the decorator only accepts one whose
41
- * constructor takes exactly what `deps` resolve to, in that order. A class taking fewer parameters
42
- * than `deps` declares still satisfies it, which is the one mismatch TypeScript's arity rules let
43
- * through — the surplus dependency is resolved and discarded.
41
+ * constructor takes exactly what `deps` resolve to, in that order — including arity, so a literal
42
+ * deps list longer than the constructor is a compile error rather than a resolved-and-discarded
43
+ * value. Optional trailing parameters admit every arity they declare, and a rest parameter admits
44
+ * any list. A deps *array* — one whose length the compiler cannot know — skips the arity check,
45
+ * which is also the deliberate spelling for declaring more dependencies than the constructor
46
+ * takes, e.g. for the dependency graph's edges.
44
47
  *
45
48
  * @since 0.3.16-canary.0
46
49
  */
47
- export declare function injectable<const Deps extends ReadonlyArray<InjectableDependency>>(deps: Deps, options?: InjectableOptions): (target: abstract new (...args: InjectedParameters<Deps>) => unknown, context: ClassDecoratorContext) => void;
50
+ export declare function injectable<const Deps extends ReadonlyArray<InjectableDependency>>(deps: Deps, options?: InjectableOptions): <Target extends abstract new (...args: InjectedParameters<Deps>) => unknown>(target: Target & (number extends Deps["length"] ? unknown : Deps["length"] extends ConstructorParameters<Target>["length"] ? unknown : never), context: ClassDecoratorContext) => void;
48
51
  export type { InjectableDependency };
49
52
  //# sourceMappingURL=injectable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"injectable.d.ts","sourceRoot":"","sources":["../../src/decorators/injectable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAO5F;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACzD,OAAO,IAAI,aAAa,CAAC;QAAE,MAAM,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC,CAAC;CACxE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,oBAAoB,CAUjE;AAID;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAChD,KAAK,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;CAClC;AAID;;;;;GAKG;AACH,KAAK,kBAAkB,CAAC,IAAI,SAAS,aAAa,CAAC,oBAAoB,CAAC,IAAI;IAC1E,CAAC,UAAU,KAAK,IAAI,MAAM,IAAI,GAAG,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;CACtE,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAExF;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,CAAC,IAAI,SAAS,aAAa,CAAC,oBAAoB,CAAC,EAC/E,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,iBAAiB,GAC1B,CAAC,MAAM,EAAE,QAAQ,MAAM,GAAG,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,OAAO,EAAE,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;AA2CjH,YAAY,EAAE,oBAAoB,EAAE,CAAC"}
1
+ {"version":3,"file":"injectable.d.ts","sourceRoot":"","sources":["../../src/decorators/injectable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAO5F;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACzD,OAAO,IAAI,aAAa,CAAC;QAAE,MAAM,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,YAAY,CAAA;KAAE,CAAC,CAAC;CACxE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,oBAAoB,CAUjE;AAID;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAChD,KAAK,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;CAClC;AAID;;;;;GAKG;AACH,KAAK,kBAAkB,CAAC,IAAI,SAAS,aAAa,CAAC,oBAAoB,CAAC,IAAI;IAC1E,CAAC,UAAU,KAAK,IAAI,MAAM,IAAI,GAAG,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;CACtE,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAExF;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,KAAK,CAAC,IAAI,SAAS,aAAa,CAAC,oBAAoB,CAAC,EAC/E,IAAI,EAAE,IAAI,EACV,OAAO,CAAC,EAAE,iBAAiB,GAC1B,CAAC,MAAM,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,OAAO,EAC5E,MAAM,EAAE,MAAM,GACZ,CAAC,MAAM,SAAS,IAAI,CAAC,QAAQ,CAAC,GAC1B,OAAO,GACP,IAAI,CAAC,QAAQ,CAAC,SAAS,qBAAqB,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,GAC5D,OAAO,GACP,KAAK,CAAC,EACd,OAAO,EAAE,qBAAqB,KAC3B,IAAI,CAAC;AA2CV,YAAY,EAAE,oBAAoB,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"injectable.js","sourceRoot":"","sources":["../../src/decorators/injectable.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAa1D;;GAEG;AACH,MAAM,UAAU,0BAA0B;IACxC,MAAM,iBAAiB,GAAwD,EAAE,CAAC;IAClF,OAAO;QACL,QAAQ,CAAC,MAAmB,EAAE,KAAmB;YAC/C,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO;YACL,OAAO,iBAAiB,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC;AA4CD;;GAEG;AACH,MAAM,UAAU,UAAU,CACxB,IAA0C,EAC1C,OAA2B;IAE3B,OAAO,UAAU,MAAa,EAAE,OAA8B;QAC5D,MAAM,qBAAqB,GAAyB,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE;YACzF,MAAM,UAAU,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;YACrD,MAAM,qBAAqB,GAAkE;gBAC3F,KAAK;gBACL,KAAK,EAAE,UAAU,CAAC,KAAK;gBACvB,QAAQ,EAAE,UAAU,CAAC,QAAQ;gBAC7B,KAAK,EAAE,UAAU,CAAC,KAAK;aACxB,CAAC;YACF,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACnE,OAAO,EAAE,GAAG,qBAAqB,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC;YACpF,CAAC;YACD,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAClC,OAAO,EAAE,GAAG,qBAAqB,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC;YAC7D,CAAC;YACD,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAClC,OAAO,EAAE,GAAG,qBAAqB,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC;YAC7D,CAAC;YACD,OAAO,qBAAqB,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,iFAAiF;QACjF,qDAAqD;QACpD,OAAO,CAAC,QAA6C,CAAC,cAAc,CAAC,GAAG;YACvE,MAAM,EAAE,qBAAqB;SAC9B,CAAC;QAEF,IAAI,OAAO,EAAE,YAAY,KAAK,SAAS,EAAE,CAAC;YACxC,MAAM,KAAK,GAAiB,OAAO,CAAC,KAAK,IAAI,WAAW,CAAC;YACzD,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAqB,EAAE,KAAK,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"injectable.js","sourceRoot":"","sources":["../../src/decorators/injectable.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAa1D;;GAEG;AACH,MAAM,UAAU,0BAA0B;IACxC,MAAM,iBAAiB,GAAwD,EAAE,CAAC;IAClF,OAAO;QACL,QAAQ,CAAC,MAAmB,EAAE,KAAmB;YAC/C,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,OAAO;YACL,OAAO,iBAAiB,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC;AAuDD;;GAEG;AACH,MAAM,UAAU,UAAU,CACxB,IAA0C,EAC1C,OAA2B;IAE3B,OAAO,UAAU,MAAa,EAAE,OAA8B;QAC5D,MAAM,qBAAqB,GAAyB,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE;YACzF,MAAM,UAAU,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;YACrD,MAAM,qBAAqB,GAAkE;gBAC3F,KAAK;gBACL,KAAK,EAAE,UAAU,CAAC,KAAK;gBACvB,QAAQ,EAAE,UAAU,CAAC,QAAQ;gBAC7B,KAAK,EAAE,UAAU,CAAC,KAAK;aACxB,CAAC;YACF,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACnE,OAAO,EAAE,GAAG,qBAAqB,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC;YACpF,CAAC;YACD,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAClC,OAAO,EAAE,GAAG,qBAAqB,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC;YAC7D,CAAC;YACD,IAAI,UAAU,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAClC,OAAO,EAAE,GAAG,qBAAqB,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,CAAC;YAC7D,CAAC;YACD,OAAO,qBAAqB,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,iFAAiF;QACjF,qDAAqD;QACpD,OAAO,CAAC,QAA6C,CAAC,cAAc,CAAC,GAAG;YACvE,MAAM,EAAE,qBAAqB;SAC9B,CAAC;QAEF,IAAI,OAAO,EAAE,YAAY,KAAK,SAAS,EAAE,CAAC;YACxC,MAAM,KAAK,GAAiB,OAAO,CAAC,KAAK,IAAI,WAAW,CAAC;YACzD,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAqB,EAAE,KAAK,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codefast/di",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "Lightweight dependency injection primitives for Codefast",
5
5
  "keywords": [
6
6
  "codefast",
@@ -274,7 +274,7 @@
274
274
  "tsx": "^4.23.12",
275
275
  "typescript": "^7.0.2",
276
276
  "vitest": "^4.1.10",
277
- "@codefast/typescript-config": "0.6.1"
277
+ "@codefast/typescript-config": "0.6.2"
278
278
  },
279
279
  "engines": {
280
280
  "node": ">=26.0.0"
@@ -60,16 +60,27 @@ export function injectable(): (target: unknown, context: ClassDecoratorContext)
60
60
 
61
61
  /**
62
62
  * @remarks Declaring dependencies constrains the class: the decorator only accepts one whose
63
- * constructor takes exactly what `deps` resolve to, in that order. A class taking fewer parameters
64
- * than `deps` declares still satisfies it, which is the one mismatch TypeScript's arity rules let
65
- * through — the surplus dependency is resolved and discarded.
63
+ * constructor takes exactly what `deps` resolve to, in that order — including arity, so a literal
64
+ * deps list longer than the constructor is a compile error rather than a resolved-and-discarded
65
+ * value. Optional trailing parameters admit every arity they declare, and a rest parameter admits
66
+ * any list. A deps *array* — one whose length the compiler cannot know — skips the arity check,
67
+ * which is also the deliberate spelling for declaring more dependencies than the constructor
68
+ * takes, e.g. for the dependency graph's edges.
66
69
  *
67
70
  * @since 0.3.16-canary.0
68
71
  */
69
72
  export function injectable<const Deps extends ReadonlyArray<InjectableDependency>>(
70
73
  deps: Deps,
71
74
  options?: InjectableOptions,
72
- ): (target: abstract new (...args: InjectedParameters<Deps>) => unknown, context: ClassDecoratorContext) => void;
75
+ ): <Target extends abstract new (...args: InjectedParameters<Deps>) => unknown>(
76
+ target: Target &
77
+ (number extends Deps["length"]
78
+ ? unknown
79
+ : Deps["length"] extends ConstructorParameters<Target>["length"]
80
+ ? unknown
81
+ : never),
82
+ context: ClassDecoratorContext,
83
+ ) => void;
73
84
 
74
85
  /**
75
86
  * @since 0.6.0