carrick 0.3.70 → 0.3.73
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/README.md +10 -2
- package/bin/carrick.mjs +4 -1
- package/dist/contract.d.ts +3 -0
- package/dist/contract.js.map +1 -1
- package/dist/init/doctor.d.ts +3 -1
- package/dist/init/doctor.js +33 -6
- package/dist/init/doctor.js.map +1 -1
- package/dist/init/install-id.d.ts +32 -0
- package/dist/init/install-id.js +118 -0
- package/dist/init/install-id.js.map +1 -0
- package/dist/init/mcp.d.ts +59 -5
- package/dist/init/mcp.js +133 -27
- package/dist/init/mcp.js.map +1 -1
- package/dist/init/remove.d.ts +4 -0
- package/dist/init/remove.js +26 -5
- package/dist/init/remove.js.map +1 -1
- package/dist/init/run.d.ts +8 -0
- package/dist/init/run.js +20 -2
- package/dist/init/run.js.map +1 -1
- package/dist/native.d.ts +25 -5
- package/dist/native.js +41 -10
- package/dist/native.js.map +1 -1
- package/dist/render.js +7 -2
- package/dist/render.js.map +1 -1
- package/package.json +6 -6
- package/sidecar/dist/src/capture/anchors.d.ts +15 -0
- package/sidecar/dist/src/capture/anchors.js +70 -5
- package/sidecar/dist/src/capture/api.d.ts +43 -4
- package/sidecar/dist/src/capture/check-classify.d.ts +2 -0
- package/sidecar/dist/src/capture/check-classify.js +28 -0
- package/sidecar/dist/src/capture/check-deep.js +1 -1
- package/sidecar/dist/src/capture/check-probe.d.ts +1 -1
- package/sidecar/dist/src/capture/check-probe.js +16 -0
- package/sidecar/dist/src/capture/deep-walk.d.ts +33 -6
- package/sidecar/dist/src/capture/deep-walk.js +81 -28
- package/sidecar/dist/src/capture/index.js +16 -6
- package/sidecar/dist/src/capture/installed-package.d.ts +58 -0
- package/sidecar/dist/src/capture/installed-package.js +311 -0
- package/sidecar/dist/src/capture/lockfile.d.ts +8 -0
- package/sidecar/dist/src/capture/lockfile.js +1 -1
- package/sidecar/dist/src/capture/node-builder.d.ts +27 -0
- package/sidecar/dist/src/capture/node-builder.js +107 -1
- package/sidecar/dist/src/capture/paths-rewrite.d.ts +23 -6
- package/sidecar/dist/src/capture/paths-rewrite.js +43 -11
- package/sidecar/dist/src/capture/self-check.js +12 -3
- package/sidecar/dist/src/capture/unresolved.d.ts +28 -0
- package/sidecar/dist/src/capture/unresolved.js +107 -0
- package/sidecar/dist/src/type-inferrer.d.ts +227 -30
- package/sidecar/dist/src/type-inferrer.js +926 -144
- package/sidecar/dist/src/type-structural-expander.d.ts +53 -3
- package/sidecar/dist/src/type-structural-expander.js +108 -19
- package/sidecar/dist/src/type-text-canonicalizer.d.ts +14 -0
- package/sidecar/dist/src/type-text-canonicalizer.js +23 -2
- package/sidecar/dist/src/validators.d.ts +10 -0
- package/sidecar/dist/src/validators.js +1 -0
|
@@ -135,6 +135,57 @@ export declare class TypeInferrer {
|
|
|
135
135
|
*/
|
|
136
136
|
private resolveParamTarget;
|
|
137
137
|
private inferResponseBody;
|
|
138
|
+
/**
|
|
139
|
+
* The wire representation a request's printed type takes. A route response
|
|
140
|
+
* is serialised as JSON by every sender this layer reads a payload out of,
|
|
141
|
+
* so it prints `toJSON()` results rather than the objects that declare them
|
|
142
|
+
* (carrick#1163). Everything else prints the declared type.
|
|
143
|
+
*/
|
|
144
|
+
private wireFormatFor;
|
|
145
|
+
/** An inferred type for a payload read out of response sends. */
|
|
146
|
+
private inferredFromRecoveredPayload;
|
|
147
|
+
/**
|
|
148
|
+
* carrick#1161: type a route response from every send in the handler the
|
|
149
|
+
* locator anchors, rather than from the one send it names.
|
|
150
|
+
*
|
|
151
|
+
* The analyzer reports one response expression per row, and on a handler
|
|
152
|
+
* that guards before it succeeds that is the guard's body. So the located
|
|
153
|
+
* expression selects the HANDLER: the function that contains it, on a row
|
|
154
|
+
* whose line is a route registration. Its returned sends are enumerated
|
|
155
|
+
* (conditional branches split), each is classified by the status it states
|
|
156
|
+
* (`responseSiteStatus`), the error and redirect branches are dropped, and
|
|
157
|
+
* the success bodies are joined exactly as the payload walk joins return
|
|
158
|
+
* statements.
|
|
159
|
+
*
|
|
160
|
+
* Returns `undefined` when this does not apply, which leaves the caller's
|
|
161
|
+
* own reading of the located expression untouched:
|
|
162
|
+
* - the row's line is not a route registration;
|
|
163
|
+
* - the located expression is neither a send nor the argument of one;
|
|
164
|
+
* - that send is not one the handler returns;
|
|
165
|
+
* - it is a success send and the only one that survives, so the join would
|
|
166
|
+
* be the located body anyway;
|
|
167
|
+
* - no joined body is the located one (a text body beside JSON ones).
|
|
168
|
+
*
|
|
169
|
+
* When the located send is an error or redirect branch and no success body
|
|
170
|
+
* survives, the route sends no body a contract can describe: an explicit
|
|
171
|
+
* `unknown` with its reason, so no later locator re-run reads the error body
|
|
172
|
+
* or the redirect location back in.
|
|
173
|
+
*/
|
|
174
|
+
private inferFromResponseSites;
|
|
175
|
+
/**
|
|
176
|
+
* True when `candidate` is a response send: a call or `new` whose result is
|
|
177
|
+
* transport machinery (by the extraction config's verified rule or the
|
|
178
|
+
* structural check), or whose callee this handler's own returns prove is a
|
|
179
|
+
* serialiser (`calleesProvenSerialiser`, which holds on a bare checkout).
|
|
180
|
+
*/
|
|
181
|
+
private isResponseSend;
|
|
182
|
+
/**
|
|
183
|
+
* The send `node` is an argument of, looking through the wrappers that do
|
|
184
|
+
* not change a payload (parentheses, `as`, `satisfies`, `!`, `await`) and a
|
|
185
|
+
* `JSON.stringify` around the body. `undefined` when the parent call is not
|
|
186
|
+
* a send or `node` is its callee.
|
|
187
|
+
*/
|
|
188
|
+
private sendReceivingArgument;
|
|
138
189
|
private inferCallResult;
|
|
139
190
|
private inferVariable;
|
|
140
191
|
private inferExpression;
|
|
@@ -524,24 +575,45 @@ export declare class TypeInferrer {
|
|
|
524
575
|
*/
|
|
525
576
|
private statesResponseInit;
|
|
526
577
|
/**
|
|
527
|
-
*
|
|
528
|
-
* `status`/`statusCode`, or a bare status code (`send(body, 404)`).
|
|
578
|
+
* What a response send states about its HTTP status (carrick#1161).
|
|
529
579
|
*
|
|
530
|
-
* Read
|
|
531
|
-
*
|
|
532
|
-
*
|
|
580
|
+
* Read in order, and the first that states anything decides:
|
|
581
|
+
*
|
|
582
|
+
* 1. an argument past the body that carries a status: a numeric literal
|
|
583
|
+
* (`send(body, 404)`), an options object (`{ status: 401 }`), or any
|
|
584
|
+
* expression whose TYPE is a status literal or a union of them
|
|
585
|
+
* (`let code: 400 | 500`). A numeric argument whose type is a plain
|
|
586
|
+
* `number` states a status the source does not fix, which is
|
|
587
|
+
* `variable`: the branch fails open into the union and is logged.
|
|
588
|
+
* 2. the send call's own RESULT type, when a member of it is typed as a
|
|
589
|
+
* status literal. A framework that types its sends records the status
|
|
590
|
+
* there, and a redirect helper's default `302` is only visible there.
|
|
591
|
+
* A result whose status member spans success and error codes (the
|
|
592
|
+
* default of a typed `json(body, status?)`) says nothing either way.
|
|
593
|
+
*
|
|
594
|
+
* A status in the FIRST argument is a field of the body and is never read.
|
|
595
|
+
* No method or framework name is consulted anywhere.
|
|
533
596
|
*/
|
|
534
|
-
private
|
|
597
|
+
private responseSiteStatus;
|
|
535
598
|
/**
|
|
536
|
-
* The HTTP status an argument states,
|
|
599
|
+
* The HTTP status codes an argument states, `'variable'` when it is a
|
|
600
|
+
* status-shaped value the source does not fix, or `undefined` when it says
|
|
601
|
+
* nothing about a status.
|
|
537
602
|
*
|
|
538
603
|
* Read from the AST first: `{ status: 400 }` in an argument position widens
|
|
539
604
|
* to `{ status: number }`, so the literal only survives syntactically. The
|
|
540
|
-
* type
|
|
541
|
-
* values in the HTTP range count
|
|
542
|
-
* domain object (`{ status: 2 }`)
|
|
605
|
+
* type read behind it catches `as const`, hoisted option objects and
|
|
606
|
+
* literal-typed variables. Only values in the HTTP range count: an
|
|
607
|
+
* arbitrary number named `status` on a domain object (`{ status: 2 }`)
|
|
608
|
+
* states nothing about transport.
|
|
609
|
+
*/
|
|
610
|
+
private statedStatusCodes;
|
|
611
|
+
/**
|
|
612
|
+
* Status codes a send call's result type records: the members (of the
|
|
613
|
+
* result, or of each part of an intersection result) typed as a status
|
|
614
|
+
* literal or a union of them. `undefined` when none is.
|
|
543
615
|
*/
|
|
544
|
-
private
|
|
616
|
+
private sendResultStatusCodes;
|
|
545
617
|
/**
|
|
546
618
|
* Peel the wrappers that do not change an expression's payload: parentheses
|
|
547
619
|
* and `await`. Unlike `unwrapExpressionNode` this KEEPS `as`/`satisfies`,
|
|
@@ -877,6 +949,11 @@ export declare class TypeInferrer {
|
|
|
877
949
|
* the route declares its request nowhere we can read.
|
|
878
950
|
*/
|
|
879
951
|
private requestContractFromRegistration;
|
|
952
|
+
/**
|
|
953
|
+
* An explicit request `InferredType` for a contract the route declares,
|
|
954
|
+
* carrying the provenance the reading recorded.
|
|
955
|
+
*/
|
|
956
|
+
private declaredRequestInferredType;
|
|
880
957
|
/**
|
|
881
958
|
* The request contract a route DECLARES, in anchor order: the handler's
|
|
882
959
|
* parameter annotation (a), the registration's schema object (b), then a
|
|
@@ -914,8 +991,9 @@ export declare class TypeInferrer {
|
|
|
914
991
|
* The shape is a CALL among the registration's arguments whose own arguments
|
|
915
992
|
* are a request part and a schema value. Neither the middleware's name nor
|
|
916
993
|
* the schema library is checked: the part is read off the string literal, and
|
|
917
|
-
* the schema is whatever
|
|
918
|
-
*
|
|
994
|
+
* the schema is whatever declares its types (`schemaContract`) — the same
|
|
995
|
+
* test anchor (b) already applies to a `schema: { body: … }` object. The
|
|
996
|
+
* contract is the schema's INPUT, what a caller sends (carrick#1101).
|
|
919
997
|
*
|
|
920
998
|
* `REQUEST_BODY_PARTS` is HTTP vocabulary for how a body is carried, not a
|
|
921
999
|
* framework list. A middleware bound to any other part (`query`, `param`,
|
|
@@ -923,19 +1001,73 @@ export declare class TypeInferrer {
|
|
|
923
1001
|
* at all is not read: publishing a query schema as the request contract would
|
|
924
1002
|
* be the same confident-and-wrong answer this anchor exists to remove.
|
|
925
1003
|
*/
|
|
926
|
-
private
|
|
1004
|
+
private validatedBodyContract;
|
|
1005
|
+
/**
|
|
1006
|
+
* The values a registration's validator middleware binds to a body part, in
|
|
1007
|
+
* argument order: every non-literal argument of a middleware call that names
|
|
1008
|
+
* a `REQUEST_BODY_PARTS` part. Whether each one IS a schema is the reader's
|
|
1009
|
+
* question (`schemaContract`), not this walk's.
|
|
1010
|
+
*/
|
|
1011
|
+
private middlewareBodySchemaValues;
|
|
1012
|
+
/**
|
|
1013
|
+
* The contract of the schema a handler validates an untyped body read with
|
|
1014
|
+
* (carrick#1166), or null.
|
|
1015
|
+
*
|
|
1016
|
+
* `read` is the located expression: the read call, or the binding that holds
|
|
1017
|
+
* it. Every call in the enclosing function that takes that value as an
|
|
1018
|
+
* argument is a candidate, and the schema is the call's receiver
|
|
1019
|
+
* (`Schema.safeParse(body)`) or one of its other arguments
|
|
1020
|
+
* (`parse(Schema, body)`). A candidate counts only when it declares schema
|
|
1021
|
+
* types (`schemaOutputType` / `schemaInputType`), so a logger or a service
|
|
1022
|
+
* call the body is also handed to is never read as a contract. No method or
|
|
1023
|
+
* library name is matched.
|
|
1024
|
+
*/
|
|
1025
|
+
private schemaConsumingRead;
|
|
1026
|
+
/**
|
|
1027
|
+
* The part a validated read names when that part is not a body, or
|
|
1028
|
+
* `undefined` (carrick#1166).
|
|
1029
|
+
*
|
|
1030
|
+
* The read is a call whose only argument is a string literal, and the
|
|
1031
|
+
* registration carries a validator middleware binding that same literal.
|
|
1032
|
+
* The part names match through the source's own literal, so no framework
|
|
1033
|
+
* vocabulary is assumed beyond `REQUEST_BODY_PARTS`, which already decides
|
|
1034
|
+
* what a body is for the middleware anchor.
|
|
1035
|
+
*/
|
|
1036
|
+
private nonBodyValidatedPart;
|
|
1037
|
+
/**
|
|
1038
|
+
* The request contract behind a VALIDATED READ: a call inside a registered
|
|
1039
|
+
* handler whose type is exactly the parsed output of a body schema the
|
|
1040
|
+
* enclosing registration declares (carrick#1101).
|
|
1041
|
+
*
|
|
1042
|
+
* The read's own type is what validation hands the handler, the schema's
|
|
1043
|
+
* output, so a locator that lands on it would publish the output as the
|
|
1044
|
+
* request. The registration is found by walking the read's ancestors to each
|
|
1045
|
+
* call or registry object whose handler contains the read and which declares
|
|
1046
|
+
* a body schema (anchor (b) or (b2)). The match is on the printed type: only
|
|
1047
|
+
* a read whose structural text equals that schema's output is substituted, so
|
|
1048
|
+
* any other expression in the handler (a query read, a payload of a different
|
|
1049
|
+
* shape) keeps its own type.
|
|
1050
|
+
*/
|
|
1051
|
+
private validatedReadRequestContract;
|
|
927
1052
|
/**
|
|
928
1053
|
* Anchor (b): the contract declared in the route's validation schema.
|
|
929
1054
|
*
|
|
930
1055
|
* `part` is `'body'` for the request contract and `'response'` for the
|
|
931
1056
|
* response contract; a `response` entry keyed by status code resolves to its
|
|
932
|
-
* success entry.
|
|
933
|
-
*
|
|
934
|
-
* when the
|
|
935
|
-
*
|
|
936
|
-
*
|
|
1057
|
+
* success entry. The body reads the schema's input and the response its
|
|
1058
|
+
* output (carrick#1101). Returns null when the registration carries no
|
|
1059
|
+
* schema, when the entry references something whose declared types cannot be
|
|
1060
|
+
* resolved, or when the schema is a plain JSON-schema literal (whose own
|
|
1061
|
+
* object type is the JSON-Schema document, not the payload — emitting that
|
|
1062
|
+
* would be worse than abstaining).
|
|
1063
|
+
*/
|
|
1064
|
+
private routeSchemaContract;
|
|
1065
|
+
/**
|
|
1066
|
+
* The value a route `schema` object declares for `part`, as a zero- or
|
|
1067
|
+
* one-element list: the `body` entry itself, or the success entry of a
|
|
1068
|
+
* status-keyed `response` map.
|
|
937
1069
|
*/
|
|
938
|
-
private
|
|
1070
|
+
private routeSchemaEntryValues;
|
|
939
1071
|
/**
|
|
940
1072
|
* The `schema` object literal carried by a route registration: scan the
|
|
941
1073
|
* registration call's arguments (or the registry object literal itself) for a
|
|
@@ -950,17 +1082,63 @@ export declare class TypeInferrer {
|
|
|
950
1082
|
*/
|
|
951
1083
|
private successStatusEntry;
|
|
952
1084
|
/**
|
|
953
|
-
* The payload type a schema entry declares
|
|
1085
|
+
* The payload type a schema entry declares, read in `direction`.
|
|
954
1086
|
*
|
|
955
1087
|
* The entry is either a REFERENCE call — `ref('CreateWidget')`, a
|
|
956
1088
|
* name-to-schema indirection whose registry is the argument the ref function
|
|
957
|
-
* was built from — or the schema value itself.
|
|
958
|
-
*
|
|
959
|
-
*
|
|
960
|
-
*
|
|
961
|
-
* and
|
|
962
|
-
|
|
963
|
-
|
|
1089
|
+
* was built from — or the schema value itself. A value that declares no type
|
|
1090
|
+
* in either direction is not a schema and yields null.
|
|
1091
|
+
*
|
|
1092
|
+
* `output` is the parsed value (`schemaOutputType`). `input` is what a caller
|
|
1093
|
+
* sends (`schemaInputType`), and a schema that declares no input member reads
|
|
1094
|
+
* its output instead, which is the whole of what is knowable about it.
|
|
1095
|
+
*
|
|
1096
|
+
* The input is decided member by member (carrick#1105). A member whose input
|
|
1097
|
+
* is `any`/`unknown` where the output is concrete is what a coercion declares
|
|
1098
|
+
* (it accepts any value and parses it into, say, a number). A top type in a
|
|
1099
|
+
* published contract disqualifies the whole row downstream, so THAT member
|
|
1100
|
+
* prints its output type, keeps the input key's optionality, and is recorded
|
|
1101
|
+
* as `coerced_input` provenance. Every other member keeps its input, so a
|
|
1102
|
+
* defaulted key beside a coerced one stays optional to send.
|
|
1103
|
+
*
|
|
1104
|
+
* Limits, each logged where it bites:
|
|
1105
|
+
* - the position walk is bounded (`walkTypePositions`), so a top type below
|
|
1106
|
+
* the bound is not compared and prints as the input declares it;
|
|
1107
|
+
* - a coerced position that cannot be substituted (its output is absent or
|
|
1108
|
+
* differs across union branches, or the printer cannot reach it inside a
|
|
1109
|
+
* tuple, behind a cycle or past the expansion depth) makes the row fall
|
|
1110
|
+
* back to the whole parsed output with every coerced member labelled. That
|
|
1111
|
+
* was the answer before the per-member reading, and it never publishes an
|
|
1112
|
+
* `unknown`.
|
|
1113
|
+
*/
|
|
1114
|
+
private schemaContract;
|
|
1115
|
+
/**
|
|
1116
|
+
* Print a schema's input with each coerced position replaced by the output's
|
|
1117
|
+
* type at that position (carrick#1105). Null when any position cannot be
|
|
1118
|
+
* substituted: its output is missing or differs across union branches, or
|
|
1119
|
+
* the printer never reached it. A partial substitution would publish an
|
|
1120
|
+
* `unknown`, so it is not an answer.
|
|
1121
|
+
*/
|
|
1122
|
+
private inputWithCoercedMembers;
|
|
1123
|
+
/**
|
|
1124
|
+
* Member positions inside `root` that are `any` or `unknown`, keyed by the
|
|
1125
|
+
* member-path notation the provenance entries use (`''` for the root,
|
|
1126
|
+
* `sub.field`, `items<0>` for an array element). Union and intersection
|
|
1127
|
+
* members share their parent's position, so `unknown | undefined` on an
|
|
1128
|
+
* optional key reads as `unknown` there.
|
|
1129
|
+
*/
|
|
1130
|
+
private topTypePositions;
|
|
1131
|
+
/**
|
|
1132
|
+
* Visit every member position of `root`, in the notation `topTypePositions`
|
|
1133
|
+
* documents. `visit` returns false to stop descending below a position;
|
|
1134
|
+
* `unionPart` is true when the type is a union or intersection part visited
|
|
1135
|
+
* at its parent's position. Callables are not descended into.
|
|
1136
|
+
*
|
|
1137
|
+
* Bounded and cycle-safe. It only has to tell a schema's input apart from its
|
|
1138
|
+
* output, so a subtree past the bound is not compared, and that is logged:
|
|
1139
|
+
* a coercion below the bound prints as its input declares it.
|
|
1140
|
+
*/
|
|
1141
|
+
private walkTypePositions;
|
|
964
1142
|
/**
|
|
965
1143
|
* Follow a schema REFERENCE call (`ref('CreateWidget')`) to the schema value
|
|
966
1144
|
* it names.
|
|
@@ -975,12 +1153,31 @@ export declare class TypeInferrer {
|
|
|
975
1153
|
private registrySchemaType;
|
|
976
1154
|
/**
|
|
977
1155
|
* The parsed output type of a schema value: the return type of its `parse`
|
|
978
|
-
* method, else a declared `_output` member
|
|
979
|
-
*
|
|
1156
|
+
* method, else a declared `_output` member, else the Standard Schema member
|
|
1157
|
+
* `~standard.types.output` (a library that exposes nothing else). Returns
|
|
1158
|
+
* undefined when none carries a usable type — including when the schema library's own types are
|
|
980
1159
|
* unavailable (an uninstalled dependency resolves the schema to `any`), which
|
|
981
1160
|
* must abstain rather than publish `any` as a contract.
|
|
982
1161
|
*/
|
|
983
1162
|
private schemaOutputType;
|
|
1163
|
+
/**
|
|
1164
|
+
* The input type of a schema value, what a caller may send (carrick#1101):
|
|
1165
|
+
* the Standard Schema member `~standard.types.input`, else a declared
|
|
1166
|
+
* `_input` member. Undefined when the schema declares neither.
|
|
1167
|
+
*
|
|
1168
|
+
* Unlike the output, an input of `unknown` is kept: it is a declared fact
|
|
1169
|
+
* (a coercion accepts any value), and `schemaContract` decides what to
|
|
1170
|
+
* publish for it. An `any` that is really an unresolved library still reads
|
|
1171
|
+
* as no input, because an unresolved schema type has no members to read.
|
|
1172
|
+
*/
|
|
1173
|
+
private schemaInputType;
|
|
1174
|
+
/**
|
|
1175
|
+
* `~standard.types.<side>` on a schema value: the Standard Schema
|
|
1176
|
+
* specification's library-neutral statement of a schema's input and output
|
|
1177
|
+
* types. `types` is declared optional, so its `undefined` is stripped before
|
|
1178
|
+
* the side is read.
|
|
1179
|
+
*/
|
|
1180
|
+
private standardSchemaType;
|
|
984
1181
|
/**
|
|
985
1182
|
* Find a node by matching expression text near a target line.
|
|
986
1183
|
*
|