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.
@@ -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`), or the one the scope member bound (`scope`).
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: ClaimSlot;
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();