@descryy/adapter-csharp 0.1.0 → 0.3.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/LICENSE +8 -0
- package/dist/adapter.d.ts +3 -8
- package/dist/adapter.d.ts.map +1 -1
- package/dist/adapter.js +57 -65
- package/dist/adapter.js.map +1 -1
- package/dist/aspnetcore.d.ts +53 -95
- package/dist/aspnetcore.d.ts.map +1 -1
- package/dist/aspnetcore.js +56 -101
- package/dist/aspnetcore.js.map +1 -1
- package/dist/client-base.d.ts +51 -88
- package/dist/client-base.d.ts.map +1 -1
- package/dist/client-base.js +46 -79
- package/dist/client-base.js.map +1 -1
- package/dist/client.d.ts +42 -106
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +83 -172
- package/dist/client.js.map +1 -1
- package/dist/efcore.d.ts +59 -113
- package/dist/efcore.d.ts.map +1 -1
- package/dist/efcore.js +119 -204
- package/dist/efcore.js.map +1 -1
- package/dist/extract.d.ts +27 -50
- package/dist/extract.d.ts.map +1 -1
- package/dist/extract.js +154 -248
- package/dist/extract.js.map +1 -1
- package/dist/nullability.d.ts +46 -78
- package/dist/nullability.d.ts.map +1 -1
- package/dist/nullability.js +47 -80
- package/dist/nullability.js.map +1 -1
- package/dist/parse.d.ts +62 -102
- package/dist/parse.d.ts.map +1 -1
- package/dist/parse.js +60 -101
- package/dist/parse.js.map +1 -1
- package/dist/projects.d.ts +24 -40
- package/dist/projects.d.ts.map +1 -1
- package/dist/projects.js +38 -65
- package/dist/projects.js.map +1 -1
- package/package.json +15 -6
package/dist/client.js
CHANGED
|
@@ -1,92 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* all yet.
|
|
2
|
+
* C# half: a call through a known HTTP client is disclosed, never silent,
|
|
3
|
+
* and mints a real `USES_API` edge when the shape allows it.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
5
|
+
* Known-type population, measured before being picked: `bench/client-call-census.mjs csharp`
|
|
6
|
+
* names `HttpClient`, `IHttpClientFactory`, `HttpRequestMessage`, `RestClient`
|
|
7
|
+
* as candidates. `RestClient` (RestSharp) has zero occurrences across all six
|
|
8
|
+
* C# reference corpora (jellyfin, eShop, eShopOnWeb, Ocelot, CleanArchitecture,
|
|
9
|
+
* Dapper). `IHttpClientFactory` only produces an `HttpClient` via
|
|
10
|
+
* `CreateClient()`; all 61 relative-path call sites in the census go through
|
|
11
|
+
* `HttpClient` variables/fields once the factory call has returned. So the
|
|
12
|
+
* known-type set is just `HttpClient`, narrower than the candidate list, on
|
|
13
|
+
* measurement. `HttpRequestMessage` is never a receiver — it's `SendAsync`'s
|
|
14
|
+
* argument — so it doesn't belong in a receiver-type set at all.
|
|
7
15
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* Origin check (DEC-260 §3): two adapters disagreeing on the same refusal
|
|
17
|
+
* shape corrupts `refusalClass` (DEC-242) once a consumer trusts it. Not
|
|
18
|
+
* Java's exact predicate: Java's "doesn't start with `/`" rule, tested
|
|
19
|
+
* against real corpora, misfired here — jellyfin and eShopOnWeb both pass a
|
|
20
|
+
* bare relative path with no leading slash (`"Users/New"`) to `HttpClient`
|
|
21
|
+
* calls resolved against `HttpClient.BaseAddress` at runtime, a shape Java's
|
|
22
|
+
* population never contains. Every such site is an integration test through
|
|
23
|
+
* `_factory.CreateClient()` (ASP.NET's in-process test client, pointed at the
|
|
24
|
+
* app under test) — a same-repository call this reader was about to mislabel
|
|
25
|
+
* as another origin. See {@link namesAnotherOrigin}. Carried back into
|
|
26
|
+
* `adapter-java`'s `relativePath` rule, which had the identical latent
|
|
27
|
+
* defect (`adapter-java` `1bfd2ae`) — both adapters now agree by construction.
|
|
20
28
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* `HttpRequestMessage` and `RestClient` as candidates. Measured directly against
|
|
31
|
-
* this row: `RestClient` (RestSharp's type) has **zero** occurrences across all
|
|
32
|
-
* six C# reference corpora (`jellyfin`, `eShop`, `eShopOnWeb`, `Ocelot`,
|
|
33
|
-
* `CleanArchitecture`, `Dapper`) — counted, not assumed, the same way DEC-129
|
|
34
|
-
* counted before admitting a corpus. `IHttpClientFactory` produces an
|
|
35
|
-
* `HttpClient` from `CreateClient()`; the client census's 61 relative-path call
|
|
36
|
-
* sites are all through `HttpClient` variables and fields once the factory call
|
|
37
|
-
* has already returned. So the known-type set here is **just `HttpClient`** —
|
|
38
|
-
* narrower than the census's candidate list, on a measurement rather than a
|
|
39
|
-
* guess, and it can widen the day a corpus exercises `RestClient` for real.
|
|
40
|
-
*
|
|
41
|
-
* `HttpRequestMessage` is not a receiver in any of the census's call sites — it
|
|
42
|
-
* is the *argument* to `SendAsync`, never the thing a verb method is called on
|
|
43
|
-
* — so it does not belong in a receiver-type set at all; including it would
|
|
44
|
-
* have been the coarser-than-node-key mistake DEC-165/187 already paid for once.
|
|
45
|
-
*
|
|
46
|
-
* ## Origin check, added after DEC-260
|
|
47
|
-
*
|
|
48
|
-
* The first pass of this file filed every candidate as "no extractor," with no
|
|
49
|
-
* distinction between a call whose literal path stays inside this repository
|
|
50
|
-
* and one that names a different origin outright — a divergence from Java's
|
|
51
|
-
* `client.ts`, which has always told the two apart. DEC-260 §3 names the
|
|
52
|
-
* consequence directly: two adapters disagreeing on the same refusal shape
|
|
53
|
-
* corrupts `refusalClass` (DEC-242) the moment a consumer trusts it, because
|
|
54
|
-
* C# would systematically over-report `capability-gap` against Java's
|
|
55
|
-
* classifier on the same underlying population.
|
|
56
|
-
*
|
|
57
|
-
* **Not Java's exact predicate, on purpose — measured, not assumed.** A first
|
|
58
|
-
* attempt reused Java's "does not start with `/`" rule verbatim and ran it
|
|
59
|
-
* against the real admitted corpora before calling the row done, per this
|
|
60
|
-
* project's own discipline. It misfired: `jellyfin` and `eShopOnWeb` both pass
|
|
61
|
-
* a **bare relative path with no leading slash** (`"Users/New"`) to `HttpClient`
|
|
62
|
-
* calls resolved against `HttpClient.BaseAddress` at run time — a shape Java's
|
|
63
|
-
* own population never contains, so Java's rule was never tested against it.
|
|
64
|
-
* Every such call site found is an integration test through
|
|
65
|
-
* `_factory.CreateClient()`, ASP.NET's in-process test client pointed at the
|
|
66
|
-
* application under test — a same-repository call this reader was about to
|
|
67
|
-
* mislabel as "another origin." See {@link namesAnotherOrigin}'s own comment
|
|
68
|
-
* for the corrected, narrower rule. This origin check was later carried back
|
|
69
|
-
* into `adapter-java`'s own `relativePath` rule, which carried the identical
|
|
70
|
-
* latent defect (`adapter-java` `1bfd2ae`) — the two adapters now agree on
|
|
71
|
-
* this shape by construction, not by two independently-tuned rules.
|
|
72
|
-
*
|
|
73
|
-
* ## Extraction, built on the shape the origin check already separated out
|
|
74
|
-
*
|
|
75
|
-
* `DEC-241` §4 named this row: `HttpClient`'s verb methods take the path as
|
|
76
|
-
* their **own first argument** — `GetAsync("/orders/{id}")`, never a
|
|
77
|
-
* separately built request object the way `OkHttpClient`/`java.net.http.HttpClient`
|
|
78
|
-
* require — the same structurally-straightforward shape Java's `RestTemplate`
|
|
79
|
-
* already extracts from. `clientCalls` below mints a real `USES_API` edge for
|
|
80
|
-
* every call whose receiver is a known client type, whose method names a
|
|
81
|
-
* literal verb, and whose path is a repository-relative literal
|
|
82
|
-
* (`relativePath`, unchanged from the origin check's own reasoning) — and
|
|
83
|
-
* files a ledger row, never silently drops the call, for every other shape:
|
|
84
|
-
* an unrecognised verb (`SendAsync`, which takes a pre-built
|
|
85
|
-
* `HttpRequestMessage` — verb and path both live inside an object this reader
|
|
86
|
-
* does not open), a non-literal path, an origin outside this repository, or a
|
|
87
|
-
* bare relative path this reader genuinely cannot place (the same
|
|
88
|
-
* `BaseAddress`-resolved shape the origin check exists to disclose rather
|
|
89
|
-
* than guess).
|
|
29
|
+
* Extraction (DEC-241 §4): `HttpClient` verb methods take the path as their
|
|
30
|
+
* own first argument — `GetAsync("/orders/{id}")`, never a separately built
|
|
31
|
+
* request object — same shape Java's `RestTemplate` extracts from.
|
|
32
|
+
* `clientCalls` mints a `USES_API` edge for a known client type, a literal
|
|
33
|
+
* verb, and a repository-relative literal path (`relativePath`); everything
|
|
34
|
+
* else files a ledger row rather than dropping silently: an unrecognised verb
|
|
35
|
+
* (`SendAsync`, verb and path live inside an `HttpRequestMessage` this reader
|
|
36
|
+
* doesn't open), a non-literal path, another origin, or an unplaceable bare
|
|
37
|
+
* relative path.
|
|
90
38
|
*/
|
|
91
39
|
import { endpointQsp, nodeId } from "@descryy/ir";
|
|
92
40
|
const CAPABILITY_GAP = { blockedBy: null, refusalClass: "capability-gap" };
|
|
@@ -106,12 +54,7 @@ function argumentKindOf(text) {
|
|
|
106
54
|
return "field";
|
|
107
55
|
return "other";
|
|
108
56
|
}
|
|
109
|
-
/**
|
|
110
|
-
* Why the first argument of a client call could not be read as a literal
|
|
111
|
-
* path — mirrors `firstArgumentTextOf`'s own reach: a bare identifier, a
|
|
112
|
-
* known environment/configuration-read expression, or something this reader
|
|
113
|
-
* does not trace.
|
|
114
|
-
*/
|
|
57
|
+
/** Why the first argument couldn't be read as a literal path — mirrors `firstArgumentTextOf`'s reach. */
|
|
115
58
|
function diagnoseArgument(text, parameterNames) {
|
|
116
59
|
if (text === undefined)
|
|
117
60
|
return CAPABILITY_GAP;
|
|
@@ -141,14 +84,11 @@ const CLIENT_METHODS = new Set([
|
|
|
141
84
|
]);
|
|
142
85
|
const KNOWN_CLIENT_TYPES = new Set(["HttpClient"]);
|
|
143
86
|
/**
|
|
144
|
-
* The HTTP verb a method name implies.
|
|
145
|
-
*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
-
*
|
|
149
|
-
* Java's `exchange`/`execute`/`uri` carry: a wrong verb mints an endpoint
|
|
150
|
-
* that joins the wrong route, or none, and root-cause traversal would follow
|
|
151
|
-
* it.
|
|
87
|
+
* The HTTP verb a method name implies. `SendAsync` takes a pre-built
|
|
88
|
+
* `HttpRequestMessage` (verb and path live inside it), so it's absent here
|
|
89
|
+
* and refused rather than defaulted — same reasoning as Java's
|
|
90
|
+
* `exchange`/`execute`/`uri`: a wrong verb mints a wrong or absent endpoint
|
|
91
|
+
* that root-cause traversal would then follow.
|
|
152
92
|
*/
|
|
153
93
|
const VERB = {
|
|
154
94
|
GetAsync: "GET",
|
|
@@ -165,10 +105,9 @@ const VERB = {
|
|
|
165
105
|
PatchAsync: "PATCH",
|
|
166
106
|
};
|
|
167
107
|
/**
|
|
168
|
-
* A path this reader will claim: repository-relative,
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
* one and keeping it would guarantee the join fails.
|
|
108
|
+
* A path this reader will claim: repository-relative, leading `/`, nothing
|
|
109
|
+
* ambiguous. Query string dropped — `SERVES_API` never mints one, keeping it
|
|
110
|
+
* would guarantee the join fails.
|
|
172
111
|
*/
|
|
173
112
|
function relativePath(value) {
|
|
174
113
|
if (!value.startsWith("/"))
|
|
@@ -179,38 +118,29 @@ function relativePath(value) {
|
|
|
179
118
|
return cut === -1 ? value : value.slice(0, cut);
|
|
180
119
|
}
|
|
181
120
|
/**
|
|
182
|
-
* A literal argument
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
* for the shapes they both actually see.
|
|
121
|
+
* A literal argument that unambiguously names a different origin: explicit
|
|
122
|
+
* scheme or protocol-relative URL. Deliberately not Java's `relativePath`
|
|
123
|
+
* predicate, even though both must agree on `refusalClass` (DEC-242) for
|
|
124
|
+
* shapes they share.
|
|
187
125
|
*
|
|
188
|
-
* Java's population (
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* `
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
* has — `BaseAddress` is a runtime value this reader does not see, so a bare
|
|
200
|
-
* relative path is genuinely undetermined, not a confirmed scope boundary.
|
|
201
|
-
* Rule 2 (precision over recall): when in doubt, the row stays in the
|
|
202
|
-
* capability-gap bucket rather than asserting a boundary this reader cannot
|
|
203
|
-
* back up. Only an unambiguous absolute form earns `out-of-scope`.
|
|
126
|
+
* Java's population (DEC-260 §1) is `RestTemplate`/`TestRestTemplate` calls —
|
|
127
|
+
* either leading-`/` or fully qualified, nothing in between, so "doesn't
|
|
128
|
+
* start with `/`" was safe there. C#'s corpora aren't the same population:
|
|
129
|
+
* `HttpClient` calls routinely pass a bare relative path with no leading
|
|
130
|
+
* slash (`"Users/New"`), resolved against `HttpClient.BaseAddress` at
|
|
131
|
+
* runtime — measured on jellyfin/eShopOnWeb, every such site an integration
|
|
132
|
+
* test through `_factory.CreateClient()`. Porting Java's predicate verbatim
|
|
133
|
+
* would file those as "another origin," a fact this reader doesn't have
|
|
134
|
+
* (`BaseAddress` is a runtime value it doesn't see) — genuinely
|
|
135
|
+
* undetermined, not a confirmed boundary. Rule 2: stays capability-gap.
|
|
136
|
+
* Only an unambiguous absolute form earns `out-of-scope`.
|
|
204
137
|
*/
|
|
205
138
|
function namesAnotherOrigin(value) {
|
|
206
139
|
return /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(value) || value.startsWith("//");
|
|
207
140
|
}
|
|
208
141
|
/**
|
|
209
|
-
* Every reference {@link clientCalls} will act on
|
|
210
|
-
*
|
|
211
|
-
* `client.test.ts` for the reconciliation this makes checkable: every
|
|
212
|
-
* candidate whose type resolves lands in either `calls` or `refusals`, with
|
|
213
|
-
* nothing else.
|
|
142
|
+
* Every reference {@link clientCalls} will act on. See `client.test.ts`:
|
|
143
|
+
* every candidate whose type resolves lands in either `calls` or `refusals`.
|
|
214
144
|
*/
|
|
215
145
|
export function candidateClientRefs(refs) {
|
|
216
146
|
return refs.filter((ref) => ref.kind === "call" &&
|
|
@@ -226,15 +156,12 @@ function stripQuery(value) {
|
|
|
226
156
|
}
|
|
227
157
|
/**
|
|
228
158
|
* DEC-097's composition, with the separator neither half is guaranteed to
|
|
229
|
-
* supply
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
* never a *missing* one. Always inserting `/` and letting `normaliseEndpointPath`'s
|
|
236
|
-
* own `/+` collapse handle the doubled case when the suffix already had one
|
|
237
|
-
* is the one join that is correct for both shapes.
|
|
159
|
+
* supply: `path` never ends in `/` (`pathPrefixOf` strips it), a call's
|
|
160
|
+
* literal may or may not start with one. A bare `+` join would silently drop
|
|
161
|
+
* the boundary (`"/api/v1" + "orders/{id}"` -> `"/api/v1orders/{id}"`), which
|
|
162
|
+
* `normaliseEndpointPath` can't recover (it fixes doubled slashes, not
|
|
163
|
+
* missing ones). Always inserting `/` and letting the `/+` collapse handle a
|
|
164
|
+
* doubled case is correct for both shapes.
|
|
238
165
|
*/
|
|
239
166
|
function joinBase(path, suffix) {
|
|
240
167
|
return `${path}/${suffix}`;
|
|
@@ -243,13 +170,10 @@ function joinBase(path, suffix) {
|
|
|
243
170
|
* Read one method's calls for outbound HTTP.
|
|
244
171
|
*
|
|
245
172
|
* `typeOfReceiver` is supplied by `extract.ts`, which already has the scope
|
|
246
|
-
* tables
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
250
|
-
* header): a per-call determination of what base, if any, this reader traced
|
|
251
|
-
* for the receiver. Called only for refs that already passed the known-client-
|
|
252
|
-
* type gate below, matching `typeOfReceiver`'s own division of labour.
|
|
173
|
+
* tables a second copy here would drift from — same division of labour as
|
|
174
|
+
* Java's `client.ts`. `clientBaseOfReceiver` is DEC-164's contract
|
|
175
|
+
* (`client-base.ts`): a per-call trace of the receiver's base, called only
|
|
176
|
+
* for refs that already passed the known-client-type gate.
|
|
253
177
|
*/
|
|
254
178
|
export function clientCalls(refs, fromId, typeOfReceiver, isTest, parameterNames, clientBaseOfReceiver) {
|
|
255
179
|
const calls = [];
|
|
@@ -276,12 +200,10 @@ export function clientCalls(refs, fromId, typeOfReceiver, isTest, parameterNames
|
|
|
276
200
|
`caller to a route it never calls.`, diagnoseArgument(ref.firstArgumentText, parameterNames));
|
|
277
201
|
continue;
|
|
278
202
|
}
|
|
279
|
-
// A literal
|
|
280
|
-
//
|
|
281
|
-
//
|
|
282
|
-
//
|
|
283
|
-
// host). Checked before `clientBase` — an absolute request URI overrides
|
|
284
|
-
// `HttpClient.BaseAddress` regardless of what this reader traced for it.
|
|
203
|
+
// A literal naming a different origin is a resolved fact, not a gap —
|
|
204
|
+
// DEC-113's out-of-scope population, same as Java's client.ts. Checked
|
|
205
|
+
// before `clientBase`: an absolute request URI overrides `BaseAddress`
|
|
206
|
+
// regardless of what was traced.
|
|
285
207
|
if (namesAnotherOrigin(ref.firstStringArgument)) {
|
|
286
208
|
refuse(`an HTTP call through ${receiverType} to \`${ref.firstStringArgument}\`, which names ` +
|
|
287
209
|
`another origin rather than a path in this repository. A scope boundary, not a gap.`, { blockedBy: null, refusalClass: "out-of-scope" });
|
|
@@ -289,10 +211,8 @@ export function clientCalls(refs, fromId, typeOfReceiver, isTest, parameterNames
|
|
|
289
211
|
}
|
|
290
212
|
const base = clientBaseOfReceiver(ref);
|
|
291
213
|
if (base.state === "unresolved") {
|
|
292
|
-
// DEC-164: never guess.
|
|
293
|
-
//
|
|
294
|
-
// corpora this row measured (see `client-base.ts`'s own header), kept
|
|
295
|
-
// rather than deleted for the day one exists.
|
|
214
|
+
// DEC-164: never guess. Zero witnesses for this branch in the six
|
|
215
|
+
// corpora measured — kept rather than deleted for the day one exists.
|
|
296
216
|
refusals.push({
|
|
297
217
|
fromId,
|
|
298
218
|
raw: ref.raw,
|
|
@@ -307,9 +227,8 @@ export function clientCalls(refs, fromId, typeOfReceiver, isTest, parameterNames
|
|
|
307
227
|
continue;
|
|
308
228
|
}
|
|
309
229
|
if (base.state === "resolved") {
|
|
310
|
-
// DEC-097: only the origin was
|
|
311
|
-
// call's
|
|
312
|
-
// traced — composes directly against `path`.
|
|
230
|
+
// DEC-097: only the origin was stripped from a resolved base, so the
|
|
231
|
+
// call's literal path composes directly against `path`.
|
|
313
232
|
calls.push({
|
|
314
233
|
fromId,
|
|
315
234
|
method: ref.name,
|
|
@@ -321,22 +240,14 @@ export function clientCalls(refs, fromId, typeOfReceiver, isTest, parameterNames
|
|
|
321
240
|
});
|
|
322
241
|
continue;
|
|
323
242
|
}
|
|
324
|
-
// `base.state === "none"
|
|
325
|
-
//
|
|
326
|
-
//
|
|
327
|
-
// this reader cannot tell whether an untraced `BaseAddress` elsewhere
|
|
328
|
-
// would give it a different meaning.
|
|
243
|
+
// `base.state === "none"`: a leading-slash literal is trusted as
|
|
244
|
+
// complete; a bare relative path isn't, since an untraced `BaseAddress`
|
|
245
|
+
// elsewhere could give it a different meaning.
|
|
329
246
|
const template = relativePath(ref.firstStringArgument);
|
|
330
247
|
if (template === undefined) {
|
|
331
|
-
//
|
|
332
|
-
//
|
|
333
|
-
//
|
|
334
|
-
// defect there. It may resolve inside this repository, against a
|
|
335
|
-
// `BaseAddress` configured elsewhere this reader does not trace, or it
|
|
336
|
-
// may not; neither an edge nor an out-of-scope claim is honest here —
|
|
337
|
-
// rule 2, applied to a classification rather than an edge. Not a
|
|
338
|
-
// per-call value and not a named blocking expression either, so
|
|
339
|
-
// `capability-gap` rather than `varies-per-call`.
|
|
248
|
+
// Bare relative path, no traced base — same shape `adapter-java`
|
|
249
|
+
// `1bfd2ae` fixed for Java. May or may not resolve inside this repo;
|
|
250
|
+
// rule 2 says neither an edge nor an out-of-scope claim is honest here.
|
|
340
251
|
refusals.push({
|
|
341
252
|
fromId,
|
|
342
253
|
raw: ref.raw,
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/efcore.d.ts
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The ORM framework extractor for C# — Entity Framework Core.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* DEC-
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* way — written from how EF Core is documented rather than from how the corpus
|
|
9
|
-
* is spelled. That is how a rule acquires zero witnesses.
|
|
4
|
+
* A `MODEL` is a framework claim, earned here. DEC-128 set the rules before
|
|
5
|
+
* extraction; DEC-180 amended four of them after counting the corpus — all
|
|
6
|
+
* four were written from EF Core's docs rather than from how the corpus is
|
|
7
|
+
* actually spelled, hence zero witnesses.
|
|
10
8
|
*
|
|
11
|
-
*
|
|
9
|
+
* Admission evidence:
|
|
12
10
|
*
|
|
13
11
|
* | evidence | jellyfin | Ocelot | eShopOnWeb | CleanArchitecture |
|
|
14
12
|
* | --- | --- | --- | --- | --- |
|
|
@@ -17,42 +15,26 @@
|
|
|
17
15
|
* | `modelBuilder.Entity<` | **0** | **0** | **0** | **0** |
|
|
18
16
|
* | `[Table(` | **0** | **0** | **0** | **0** |
|
|
19
17
|
*
|
|
20
|
-
*
|
|
18
|
+
* Admission grounds:
|
|
19
|
+
* 1. `DbSet<T>` on a `DbContext` — primary, witnessed in 3 of 4 corpora.
|
|
20
|
+
* 2. `IEntityTypeConfiguration<T>` — replaces DEC-128's `modelBuilder.Entity<T>()`,
|
|
21
|
+
* the same fact in a form the corpus doesn't contain.
|
|
22
|
+
* 3. `[Table]` and `modelBuilder.Entity<T>()` are still read where they
|
|
23
|
+
* appear but reported unwitnessed (`0 of 0`) — a rule with zero witnesses
|
|
24
|
+
* can't be shown to work or fail.
|
|
21
25
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* `modelBuilder.Entity<T>()` rule, which is the same fact written in a form
|
|
26
|
-
* the corpus does not contain.
|
|
27
|
-
* 3. `[Table]` and `modelBuilder.Entity<T>()` are still **read** where they
|
|
28
|
-
* appear, and are reported as **unwitnessed** — `0 of 0`, undefined, never as
|
|
29
|
-
* passing. A rule with zero witnesses cannot be shown to work or to fail, and
|
|
30
|
-
* its green is the green of a branch never taken.
|
|
26
|
+
* Refused: a type in a `Models`/`Entities` namespace with no mapping evidence
|
|
27
|
+
* (the `IFoo` guess this project forbids), and an owned type via `OwnsOne`
|
|
28
|
+
* (shares its owner's table, has none of its own).
|
|
31
29
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
30
|
+
* Generated migrations are excluded and the exclusion counted: 1,338 of
|
|
31
|
+
* jellyfin's 1,339 `ToTable` calls, and 50 of eShopOnWeb's 51, are inside
|
|
32
|
+
* `Migrations/` under `<auto-generated />` — reading them unexcluded is
|
|
33
|
+
* reading almost only generated code.
|
|
35
34
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* `jellyfin`'s 1,339 `ToTable` calls are inside `Migrations/`**, under a
|
|
40
|
-
* `// <auto-generated />` header, and 50 of `eShopOnWeb`'s 51. Those files are
|
|
41
|
-
* EF Core's serialised model from whenever someone last scaffolded a migration —
|
|
42
|
-
* an artefact of an operation, read as evidence about the world.
|
|
43
|
-
*
|
|
44
|
-
* An extractor reading them without excluding them is, to three significant
|
|
45
|
-
* figures, reading **only** generated code. So they are excluded — and the count
|
|
46
|
-
* is **reported**, because a silent exclusion of 1,338 of 1,339 is a correct
|
|
47
|
-
* decision that looks identical to a reader that never found them.
|
|
48
|
-
*
|
|
49
|
-
* ## No corpus can exercise the provenance rule
|
|
50
|
-
*
|
|
51
|
-
* `Dapper`, `NHibernate` and `linq2db` occur **zero** times across all four
|
|
52
|
-
* corpora. There is no C# repository here in which a rival ORM's types are
|
|
53
|
-
* present for these rules to correctly refuse — the identical hole the Java
|
|
54
|
-
* control set has. Stated before extraction rather than discovered after a green
|
|
55
|
-
* run, and every report carries the EF negative control as `0 of 0 — undefined`.
|
|
35
|
+
* No corpus exercises the provenance rule: `Dapper`, `NHibernate`, `linq2db`
|
|
36
|
+
* occur zero times across all four corpora (same hole as the Java control
|
|
37
|
+
* set) — every report carries the EF negative control as `0 of 0 — undefined`.
|
|
56
38
|
*/
|
|
57
39
|
import type { CsFile } from "./parse.ts";
|
|
58
40
|
import { type NullableContext } from "./nullability.ts";
|
|
@@ -66,20 +48,11 @@ export interface EfColumn {
|
|
|
66
48
|
export interface EfModel {
|
|
67
49
|
readonly typeName: string;
|
|
68
50
|
/**
|
|
69
|
-
* Namespace-qualified
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
* declaration sharing a resolved name became a `MODEL` — `eShopOnWeb` emitted
|
|
75
|
-
* a second `Basket` for its Razor `ViewComponent` and a second `CatalogItem`
|
|
76
|
-
* for its Blazor DTO, each with the entity's columns attached to the wrong
|
|
77
|
-
* type.
|
|
78
|
-
*
|
|
79
|
-
* So a conservative refusal in this file was holding a defect in another one
|
|
80
|
-
* shut. Widening the refusal was correct and it was also the thing that fired
|
|
81
|
-
* the second bug — which is the argument for re-running precision after a
|
|
82
|
-
* widening rather than after a release.
|
|
51
|
+
* Namespace-qualified — the simple name doesn't identify a type. The
|
|
52
|
+
* consumer decides `MODEL` vs `CLASS` from this map; keying on `typeName`
|
|
53
|
+
* was invisible until simple-name collisions started resolving, at which
|
|
54
|
+
* point `eShopOnWeb` emitted a second `Basket`/`CatalogItem` (Razor
|
|
55
|
+
* `ViewComponent`/Blazor DTO) each carrying the entity's columns.
|
|
83
56
|
*/
|
|
84
57
|
readonly fqn: string;
|
|
85
58
|
readonly path: readonly string[];
|
|
@@ -99,20 +72,12 @@ export interface EfCensus {
|
|
|
99
72
|
readonly generatedToTableSkipped: number;
|
|
100
73
|
/**
|
|
101
74
|
* Entities named by a mapping whose simple name is declared more than once.
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* `
|
|
107
|
-
*
|
|
108
|
-
* one that looks entirely healthy because a model *is* emitted with plausible
|
|
109
|
-
* columns.
|
|
110
|
-
*
|
|
111
|
-
* This is the mistake `adapter-java` records for `airbyte`, arriving in C#: a
|
|
112
|
-
* `Map<string, Declared>` keeps the last (or first) of several and resolves
|
|
113
|
-
* every reference to it. Two declarations is genuinely ambiguous and the
|
|
114
|
-
* `DbSet<T>` argument is rarely qualified, so there is nothing to break the tie
|
|
115
|
-
* with. Refused, and counted so the refusal is visible.
|
|
75
|
+
* Refused rather than guessed: `eShopOnWeb` declares `Basket`,
|
|
76
|
+
* `CatalogBrand`, `CatalogItem`, `CatalogType` twice each — entity in
|
|
77
|
+
* `ApplicationCore/Entities`, view DTO in `BlazorShared/Models`. First-wins
|
|
78
|
+
* would publish the DTO's columns as the entity's — the `adapter-java`
|
|
79
|
+
* `airbyte` mistake, arriving in C#. `DbSet<T>`'s argument is rarely
|
|
80
|
+
* qualified, so there's nothing to break the tie with — refused and counted.
|
|
116
81
|
*/
|
|
117
82
|
readonly ambiguousEntityNames: readonly string[];
|
|
118
83
|
/**
|
|
@@ -126,64 +91,45 @@ export interface EfCensus {
|
|
|
126
91
|
readonly unresolved: number;
|
|
127
92
|
};
|
|
128
93
|
/**
|
|
129
|
-
* Properties refused because their declared type is a
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
* **The owned-type rule DEC-128 §2 states has no readable witness.**
|
|
133
|
-
* `eShopOnWeb`'s only `OwnsOne` calls are inside `Migrations/*.Designer.cs`,
|
|
134
|
-
* which are generated and correctly excluded, so `Address` and
|
|
135
|
-
* `CatalogItemOrdered` are never marked owned. Reading them anyway would have
|
|
136
|
-
* published `ShipToAddress` as one non-nullable column, when EF spreads an
|
|
137
|
-
* owned type across several columns of the owner's table under names this
|
|
138
|
-
* reader cannot compute.
|
|
94
|
+
* Properties refused because their declared type is a repo-declared class —
|
|
95
|
+
* a navigation or owned type, not a scalar column.
|
|
139
96
|
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
97
|
+
* DEC-128 §2's owned-type rule has no readable witness: `eShopOnWeb`'s only
|
|
98
|
+
* `OwnsOne` calls are inside generated `Migrations/*.Designer.cs`, correctly
|
|
99
|
+
* excluded, so `Address`/`CatalogItemOrdered` are never marked owned.
|
|
100
|
+
* Reading them anyway would publish `ShipToAddress` as one non-nullable
|
|
101
|
+
* column when EF spreads an owned type across several columns under names
|
|
102
|
+
* this reader can't compute. So the rule rests on declaration, not
|
|
103
|
+
* configuration: any property typed as a repo-declared `class`/`record`/
|
|
104
|
+
* `interface` is not a scalar column. Enums and structs are, and stay.
|
|
144
105
|
*/
|
|
145
106
|
readonly navigationsRefused: number;
|
|
146
107
|
/** Which rule *won* precedence for each admitted model. */
|
|
147
108
|
readonly admittedBy: Readonly<Record<EfModel["admittedBy"], number>>;
|
|
148
109
|
/**
|
|
149
|
-
* How many entities
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* corpus** — which reads as *the rule never fires* when it means *nothing
|
|
155
|
-
* needed it to*. A rule that fires and never wins is not an unwitnessed rule,
|
|
156
|
-
* and the distinction is exactly the one DEC-180 was written to protect.
|
|
110
|
+
* How many entities each rule saw, independent of which won. Reported
|
|
111
|
+
* beside `admittedBy` because `DbSet<T>` outranks `IEntityTypeConfiguration<T>`
|
|
112
|
+
* and names the same entities, so `admittedBy.configuration` is 0 on every
|
|
113
|
+
* corpus — a rule that fires and never wins is not the same as an
|
|
114
|
+
* unwitnessed rule, the distinction DEC-180 protects.
|
|
157
115
|
*/
|
|
158
116
|
readonly evidenceFor: Readonly<Record<EfModel["admittedBy"], number>>;
|
|
159
117
|
}
|
|
160
118
|
/**
|
|
161
|
-
* Does this file import EF Core at all?
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* nine, silently.
|
|
169
|
-
*
|
|
170
|
-
* `parse.ts` already says a `global using` is *"in force for every file in the
|
|
171
|
-
* project, not just this one"* and models the flag. This is the first consumer
|
|
172
|
-
* to act on it. Modern C# leans on it heavily — .NET 6 onward emits an implicit
|
|
173
|
-
* global-usings file per project — so a reader that ignores it fails on new
|
|
174
|
-
* codebases specifically.
|
|
175
|
-
*
|
|
176
|
-
* Scoped by **assembly**, because that is what a project is. A global using in
|
|
177
|
-
* one project does not reach another.
|
|
119
|
+
* Does this file import EF Core at all? A `global using` counts, in force
|
|
120
|
+
* across the whole assembly — not an edge case: `eShop`'s `OrderingContext`
|
|
121
|
+
* declares nine `DbSet<T>` with `Microsoft.EntityFrameworkCore` arriving via
|
|
122
|
+
* `GlobalUsings.cs` three files away; file-local-only usings read zero models
|
|
123
|
+
* from a corpus with nine. Modern C# (.NET 6+ implicit global usings) leans
|
|
124
|
+
* on this heavily. Scoped by assembly — a global using in one project doesn't
|
|
125
|
+
* reach another.
|
|
178
126
|
*/
|
|
179
127
|
export declare function importsEfCore(file: CsFile, globalsByAssembly?: ReadonlyMap<string, boolean>): boolean;
|
|
180
128
|
/**
|
|
181
|
-
* Is this file generated?
|
|
182
|
-
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
* `Migrations/` path catches the migration classes beside the snapshot, which
|
|
186
|
-
* carry no header of their own in every version.
|
|
129
|
+
* Is this file generated? Two signals needed: `// <auto-generated />` (the
|
|
130
|
+
* language convention, EF Core's scaffolder emits it) and the `Migrations/`
|
|
131
|
+
* path (catches migration classes beside the snapshot, which lack the header
|
|
132
|
+
* in every version).
|
|
187
133
|
*/
|
|
188
134
|
export declare function isGenerated(path: string, source: string): boolean;
|
|
189
135
|
export interface EfInput {
|