carrick 0.3.127 → 0.3.129
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/package.json +6 -6
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/sidecar/dist/src/capture/anchors.js +5 -1
- package/sidecar/dist/src/capture/check-classify.d.ts +8 -1
- package/sidecar/dist/src/capture/check-classify.js +21 -1
- package/sidecar/dist/src/capture/check-probe.d.ts +7 -7
- package/sidecar/dist/src/capture/check-probe.js +13 -14
- package/sidecar/dist/src/capture/check.js +5 -5
- package/sidecar/dist/src/index.js +43 -4
- package/sidecar/dist/src/library-claims.d.ts +63 -3
- package/sidecar/dist/src/library-claims.js +380 -39
- package/sidecar/dist/src/retype.js +36 -0
- package/sidecar/dist/src/server-labels.d.ts +29 -0
- package/sidecar/dist/src/server-labels.js +45 -0
- package/sidecar/dist/src/stated-params.d.ts +138 -0
- package/sidecar/dist/src/stated-params.js +547 -0
- package/sidecar/dist/src/type-inferrer.d.ts +89 -1
- package/sidecar/dist/src/type-inferrer.js +429 -17
- package/sidecar/dist/src/types.d.ts +76 -3
- package/sidecar/dist/src/unwidened.d.ts +11 -2
- package/sidecar/dist/src/unwidened.js +50 -3
- package/sidecar/dist/src/validators.d.ts +228 -59
- package/sidecar/dist/src/validators.js +45 -2
|
@@ -200,6 +200,31 @@ export interface InferRequest extends BaseRequest {
|
|
|
200
200
|
* how each relates to what it read (`InferredType.model_symbol_relation`).
|
|
201
201
|
*/
|
|
202
202
|
model_symbols?: ModelSymbol[];
|
|
203
|
+
/**
|
|
204
|
+
* carrick#2674: the service's settled server-framework claims. Each is
|
|
205
|
+
* verified again in the service's program, and the members the verified
|
|
206
|
+
* ones name are what a route handler's own parameters are read through:
|
|
207
|
+
* the reply a `send` op's payload slot states, and the request body a
|
|
208
|
+
* receive op's `request.body` path names. Absent or empty, nothing is read.
|
|
209
|
+
*/
|
|
210
|
+
server_claims?: ServerClaims;
|
|
211
|
+
}
|
|
212
|
+
/** The server-framework claims an `infer` request reads handler parameters through (carrick#2674). */
|
|
213
|
+
export interface ServerClaims {
|
|
214
|
+
/** The service root module resolution starts from, as on `verify_library_claims`. */
|
|
215
|
+
from_dir: string;
|
|
216
|
+
scan_root?: string;
|
|
217
|
+
/**
|
|
218
|
+
* As the client sends them: each is read through the library-check schema
|
|
219
|
+
* on its own, and a refused one is dropped (`settledServerChecks`).
|
|
220
|
+
*/
|
|
221
|
+
checks: unknown[];
|
|
222
|
+
/**
|
|
223
|
+
* Per package specifier, the type-only packages the store says its surface
|
|
224
|
+
* re-exports (the store's `type_packages`): a reply member declared in one
|
|
225
|
+
* of them is the package's own.
|
|
226
|
+
*/
|
|
227
|
+
type_packages?: Record<string, string[]>;
|
|
203
228
|
}
|
|
204
229
|
/** A type the model named for the row `alias` is for (carrick#2111). */
|
|
205
230
|
export interface ModelSymbol {
|
|
@@ -423,10 +448,21 @@ export interface ClaimSlot {
|
|
|
423
448
|
}
|
|
424
449
|
/**
|
|
425
450
|
* A name the call does not carry: the one the maker's `name` slot bound to
|
|
426
|
-
* the instance (`maker`),
|
|
451
|
+
* the instance (`maker`), the one the scope member bound (`scope`), or the
|
|
452
|
+
* key path the op's value sits under in a `collects` object (`key`, #2474
|
|
453
|
+
* R6a).
|
|
427
454
|
*/
|
|
428
455
|
export interface BoundName {
|
|
429
|
-
bound: 'maker' | 'scope';
|
|
456
|
+
bound: 'maker' | 'scope' | 'key';
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Where a router member takes its procedures (#2474 R6a, contract amendment
|
|
460
|
+
* 3 on carrick#2434): an object at argument `arg` (or its property `key`)
|
|
461
|
+
* whose property values are procedures or nested collections, each named by
|
|
462
|
+
* its key; nested keys join with `join`.
|
|
463
|
+
*/
|
|
464
|
+
export interface Collects extends ClaimSlot {
|
|
465
|
+
join: string;
|
|
430
466
|
}
|
|
431
467
|
/**
|
|
432
468
|
* The function or client a call runs (label structure v2, carrick#2434): a
|
|
@@ -459,6 +495,8 @@ export interface RequestAt {
|
|
|
459
495
|
path?: string[];
|
|
460
496
|
url?: string[];
|
|
461
497
|
method?: string[];
|
|
498
|
+
/** The member that holds the request's body (carrick#2674). */
|
|
499
|
+
body?: string[];
|
|
462
500
|
}
|
|
463
501
|
/** The closed role list; the role alone picks the checks a claim needs. */
|
|
464
502
|
export type LibraryRole = 'http_client' | 'graphql_client' | 'broker' | 'in_process_bus' | 'socket' | 'server_framework' | 'none';
|
|
@@ -509,7 +547,8 @@ export type LibraryClaim = {
|
|
|
509
547
|
/** A member that returns a receiver bound to a name (a channel, room or queue). */
|
|
510
548
|
kind: 'scope';
|
|
511
549
|
member: string;
|
|
512
|
-
name
|
|
550
|
+
/** Exactly one of `name` and `collects` (#2474 R6a). */
|
|
551
|
+
name?: ClaimSlot;
|
|
513
552
|
path?: string[];
|
|
514
553
|
on?: ClaimOn;
|
|
515
554
|
of?: string;
|
|
@@ -525,6 +564,8 @@ export type LibraryClaim = {
|
|
|
525
564
|
yields?: Yields;
|
|
526
565
|
/** Route fields (#2474 R0): the instance handed here is served under `name`. */
|
|
527
566
|
mounts?: ClaimSlot;
|
|
567
|
+
/** Procedure routers (#2474 R6a): the member collects procedures by key and returns the collection. */
|
|
568
|
+
collects?: Collects;
|
|
528
569
|
} | {
|
|
529
570
|
kind: 'op';
|
|
530
571
|
op: LibraryOp;
|
|
@@ -967,8 +1008,40 @@ export interface SurfaceMember {
|
|
|
967
1008
|
name: string;
|
|
968
1009
|
/** Declared by the receiver's home packages (not only inherited from another package). */
|
|
969
1010
|
own: boolean;
|
|
1011
|
+
/**
|
|
1012
|
+
* The members the parameters of a function this member takes declare
|
|
1013
|
+
* (carrick#2674): what a receive op's `request` field names its member
|
|
1014
|
+
* paths in. Under a cap of their own, apart from the main one.
|
|
1015
|
+
*/
|
|
1016
|
+
handlers?: SurfaceHandler[];
|
|
970
1017
|
signatures: SurfaceSignature[];
|
|
971
1018
|
}
|
|
1019
|
+
/**
|
|
1020
|
+
* A function a member takes at argument `arg`, or at `key` of the options
|
|
1021
|
+
* object there, and the parameters of it that declare members. A handler the
|
|
1022
|
+
* member's overloads state alike is listed once, from the first overload.
|
|
1023
|
+
*/
|
|
1024
|
+
export interface SurfaceHandler {
|
|
1025
|
+
arg: number;
|
|
1026
|
+
key?: string;
|
|
1027
|
+
params: SurfaceHandlerParam[];
|
|
1028
|
+
}
|
|
1029
|
+
/** One parameter of a handler, with the members its type declares (none: not listed). */
|
|
1030
|
+
export interface SurfaceHandlerParam {
|
|
1031
|
+
param: number;
|
|
1032
|
+
name: string;
|
|
1033
|
+
/** The parameter's type as the declarations print it, truncated. */
|
|
1034
|
+
type: string;
|
|
1035
|
+
members: SurfaceHandlerMember[];
|
|
1036
|
+
}
|
|
1037
|
+
/** A member of a handler's parameter, by path from the parameter, to two levels. */
|
|
1038
|
+
export interface SurfaceHandlerMember {
|
|
1039
|
+
path: string[];
|
|
1040
|
+
type: string;
|
|
1041
|
+
optional: boolean;
|
|
1042
|
+
/** Callable (a method or a function-typed property). */
|
|
1043
|
+
function: boolean;
|
|
1044
|
+
}
|
|
972
1045
|
/** One receiver the verifier can read claims on, in its receiver grammar, with what it declares. */
|
|
973
1046
|
export interface SurfaceReceiver {
|
|
974
1047
|
receiver: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The unwidened reading of a producer's response (carrick#1516)
|
|
2
|
+
* The unwidened reading of a producer's response (carrick#1516), and of a
|
|
3
|
+
* consumer's request body (carrick#2011).
|
|
3
4
|
*
|
|
4
5
|
* A handler that returns `{ scope: row.parentId ? 'specific' : 'all' }` sends
|
|
5
6
|
* one of two strings, but its inferred return type says `scope: string`:
|
|
@@ -78,8 +79,16 @@ export declare function pathOf(read: Node): Node[];
|
|
|
78
79
|
/**
|
|
79
80
|
* The insertions that mark every literal inside `fn` whose widening the
|
|
80
81
|
* reading drops. Positions are original-file positions.
|
|
82
|
+
*
|
|
83
|
+
* `sent` is given for a request body a consumer sends (carrick#2011), and is
|
|
84
|
+
* the expression the inference read. A literal handed to any other call is
|
|
85
|
+
* then left alone: keeping `useState('open')` narrow narrows the state's
|
|
86
|
+
* setter too, and code elsewhere that calls the setter with another value
|
|
87
|
+
* sits in a file the reading's guard never checks. A response's reading
|
|
88
|
+
* passes no `sent`: what the handler hands its callees is part of what it
|
|
89
|
+
* returns.
|
|
81
90
|
*/
|
|
82
|
-
export declare function literalInsertions(fn: Node): Insertion[];
|
|
91
|
+
export declare function literalInsertions(fn: Node, sent?: Node): Insertion[];
|
|
83
92
|
/** Deduplicated, in text order (a closer before an opener at one position). */
|
|
84
93
|
export declare function normalise(insertions: Insertion[]): Insertion[];
|
|
85
94
|
export declare function applyInsertions(text: string, insertions: Insertion[]): string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The unwidened reading of a producer's response (carrick#1516)
|
|
2
|
+
* The unwidened reading of a producer's response (carrick#1516), and of a
|
|
3
|
+
* consumer's request body (carrick#2011).
|
|
3
4
|
*
|
|
4
5
|
* A handler that returns `{ scope: row.parentId ? 'specific' : 'all' }` sends
|
|
5
6
|
* one of two strings, but its inferred return type says `scope: string`:
|
|
@@ -111,15 +112,23 @@ function hasDeclaredReturn(node) {
|
|
|
111
112
|
/**
|
|
112
113
|
* The insertions that mark every literal inside `fn` whose widening the
|
|
113
114
|
* reading drops. Positions are original-file positions.
|
|
115
|
+
*
|
|
116
|
+
* `sent` is given for a request body a consumer sends (carrick#2011), and is
|
|
117
|
+
* the expression the inference read. A literal handed to any other call is
|
|
118
|
+
* then left alone: keeping `useState('open')` narrow narrows the state's
|
|
119
|
+
* setter too, and code elsewhere that calls the setter with another value
|
|
120
|
+
* sits in a file the reading's guard never checks. A response's reading
|
|
121
|
+
* passes no `sent`: what the handler hands its callees is part of what it
|
|
122
|
+
* returns.
|
|
114
123
|
*/
|
|
115
|
-
export function literalInsertions(fn) {
|
|
124
|
+
export function literalInsertions(fn, sent) {
|
|
116
125
|
const out = [];
|
|
117
126
|
const visit = (node) => {
|
|
118
127
|
// A type states no value, and a parameter's default decides what its
|
|
119
128
|
// callers may pass, not what the function returns.
|
|
120
129
|
if (Node.isTypeNode(node) || Node.isParameterDeclaration(node))
|
|
121
130
|
return;
|
|
122
|
-
if (isMarkableLiteral(node)) {
|
|
131
|
+
if (isMarkableLiteral(node) && (sent === undefined || !handedToAnotherCall(node, sent))) {
|
|
123
132
|
out.push({ pos: node.getStart(), text: OPEN, closes: false });
|
|
124
133
|
out.push({ pos: node.getEnd(), text: CLOSE, closes: true });
|
|
125
134
|
return;
|
|
@@ -129,6 +138,44 @@ export function literalInsertions(fn) {
|
|
|
129
138
|
visit(fn);
|
|
130
139
|
return out;
|
|
131
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Whether `literal` is an argument, at any depth, of a call that is not the
|
|
143
|
+
* send: walking up, a call or `new` holds it as an argument before the walk
|
|
144
|
+
* reaches `sent` (the expression the request inference read) or the send
|
|
145
|
+
* call `sent` is.
|
|
146
|
+
*
|
|
147
|
+
* A literal that initialises a `const` reaches a call through the const's
|
|
148
|
+
* name (`const initial = 'open'; useState(initial)`), so the walk follows
|
|
149
|
+
* every identifier of that name in the const's scope, and a name it cannot
|
|
150
|
+
* follow (a destructuring pattern) counts as handed on. Matching by name, not
|
|
151
|
+
* by symbol, can only skip more literals.
|
|
152
|
+
*/
|
|
153
|
+
function handedToAnotherCall(literal, sent, depth = 0) {
|
|
154
|
+
if (depth > MAX_FOLLOW_DEPTH)
|
|
155
|
+
return true;
|
|
156
|
+
let current = literal;
|
|
157
|
+
for (let parent = current.getParent(); parent; parent = current.getParent()) {
|
|
158
|
+
if (current === sent)
|
|
159
|
+
return false;
|
|
160
|
+
if ((Node.isCallExpression(parent) || Node.isNewExpression(parent)) &&
|
|
161
|
+
parent.getArguments().includes(current)) {
|
|
162
|
+
return parent !== sent;
|
|
163
|
+
}
|
|
164
|
+
if (Node.isVariableDeclaration(parent) && parent.getInitializer() === current) {
|
|
165
|
+
const name = parent.getNameNode();
|
|
166
|
+
if (!Node.isIdentifier(name))
|
|
167
|
+
return true;
|
|
168
|
+
const scope = parent.getFirstAncestor(isFunctionWithBody) ?? parent.getSourceFile();
|
|
169
|
+
return scope
|
|
170
|
+
.getDescendantsOfKind(SyntaxKind.Identifier)
|
|
171
|
+
.some((use) => use !== name &&
|
|
172
|
+
use.getText() === name.getText() &&
|
|
173
|
+
handedToAnotherCall(use, sent, depth + 1));
|
|
174
|
+
}
|
|
175
|
+
current = parent;
|
|
176
|
+
}
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
132
179
|
/** Whether `node` is a literal value the reading marks `as const`. */
|
|
133
180
|
function isMarkableLiteral(node) {
|
|
134
181
|
const kind = node.getKind();
|