candor-ts 0.40.1 → 0.40.3

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 (3) hide show
  1. package/README.md +20 -0
  2. package/package.json +6 -3
  3. package/scan.mjs +1096 -73
package/README.md CHANGED
@@ -185,6 +185,26 @@ functions analyzed): its DI-style fs injection means many functions read `Unknow
185
185
  that's the contract working, not noise. The report says "can reach", never "does"; an absent
186
186
  literal is never a claim of absence.
187
187
 
188
+ **Framework dependency injection (spec §2's bounded-CHA clause).** rimraf's injection is a function-valued
189
+ parameter, which reads `Unknown`. A DI *container* is measured separately, on NestJS 10 with an executed fixture:
190
+
191
+ - a provider entry `{ provide: Store, useClass | useValue | useFactory | useExisting: … }` whose token is a project
192
+ CLASS is read as a conversion: the substitute joins `Store`'s candidates, so `this.store.save()` is charged the
193
+ union of `Store.save` and the substitute's `save` (SOUNDNESS R1061 — silent before, all three forms executed);
194
+ - a parameter typed by an INTERFACE (`@Inject("SINK") sink: Sink`) dispatches over the project's visible
195
+ implementors of `Sink`, so a `useClass` that `implements Sink` is charged; a `useValue` object literal that
196
+ implements nothing reads `Unknown` (`dispatch:`).
197
+
198
+ - the TOKEN is read through the checker's type, so `const TOK = Store`, an imported token, `TOKENS.store` and a
199
+ `.map` over `[Store]` name `Store`; a helper's `token`/`impl` parameter is read through its visible call sites; a
200
+ token typed `Function`/`Type<any>` joins its substitute to every project class it is assignable to (R1061);
201
+ - a substitute the scan cannot name (`useClass: impls[i]` typed `Type<Store>`, a `useValue` typed `any`) makes a
202
+ dispatch on the token class read `Unknown` (`dispatch:`).
203
+
204
+ **Named miss:** a provider list the scan cannot see at all (one imported from an unscanned package) and a substitute
205
+ supplied by a dependency for a token the dependency owns. Gate a DI-heavy service with `deny <E> Unknown` as well as
206
+ `deny <E>`.
207
+
188
208
  ## Cross-engine consistency — machine-checked
189
209
 
190
210
  candor-ts is one of the **four code engines** (with the reference engine candor-java, the Rust
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "candor-ts",
3
- "version": "0.40.1",
3
+ "version": "0.40.3",
4
4
  "mcpName": "io.github.tombaldwin/candor",
5
5
  "description": "candor for TypeScript — per-function side effects, transitively, with a policy gate (candor-spec 0.40)",
6
6
  "type": "module",
7
7
  "dependencies": {
8
- "@types/node": "^25.9.2",
9
- "typescript": "^6.0.3"
8
+ "@types/node": "25.9.2",
9
+ "typescript": "6.0.3"
10
10
  },
11
11
  "bin": {
12
12
  "candor-ts": "./scan.mjs",
@@ -21,6 +21,8 @@
21
21
  },
22
22
  "scripts": {
23
23
  "lint": "eslint *.mjs",
24
+ "prepack": "node -e \"require('fs').copyFileSync('package-lock.json','npm-shrinkwrap.json')\"",
25
+ "postpack": "node -e \"require('fs').rmSync('npm-shrinkwrap.json',{force:true})\"",
24
26
  "test": "npm run lint && node --test test-unit.mjs && node test.mjs --parallel && node test-mcp.mjs && node test-lsp.mjs && node test-watch.mjs && npm run test:probe && npm run test:fuzz",
25
27
  "test:unit": "node --test test-unit.mjs",
26
28
  "test:probe": "node fabrication_probe.mjs",
@@ -45,6 +47,7 @@
45
47
  "node": ">=20"
46
48
  },
47
49
  "files": [
50
+ "npm-shrinkwrap.json",
48
51
  "Cases.ts",
49
52
  "scan.mjs",
50
53
  "query.mjs",