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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "carrick",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.129",
|
|
4
4
|
"carrickCache": {
|
|
5
5
|
"cache_version": 22,
|
|
6
6
|
"intent_cache_version": 2
|
|
@@ -113,11 +113,11 @@
|
|
|
113
113
|
"zod": "^3.23.0"
|
|
114
114
|
},
|
|
115
115
|
"optionalDependencies": {
|
|
116
|
-
"@carrick-tools/cli-darwin-arm64": "0.3.
|
|
117
|
-
"@carrick-tools/cli-darwin-x64": "0.3.
|
|
118
|
-
"@carrick-tools/cli-linux-arm64": "0.3.
|
|
119
|
-
"@carrick-tools/cli-linux-x64": "0.3.
|
|
120
|
-
"@carrick-tools/cli-win32-x64": "0.3.
|
|
116
|
+
"@carrick-tools/cli-darwin-arm64": "0.3.129",
|
|
117
|
+
"@carrick-tools/cli-darwin-x64": "0.3.129",
|
|
118
|
+
"@carrick-tools/cli-linux-arm64": "0.3.129",
|
|
119
|
+
"@carrick-tools/cli-linux-x64": "0.3.129",
|
|
120
|
+
"@carrick-tools/cli-win32-x64": "0.3.129"
|
|
121
121
|
},
|
|
122
122
|
"devDependencies": {
|
|
123
123
|
"@types/node": "^24.13.3"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "carrick",
|
|
3
3
|
"description": "Claude Code plugin for Carrick, which indexes TypeScript codebases across service and repository boundaries. After each edit it adds the file's routes, calls, and cross-service type mismatches to the session, and it registers Carrick's language server. It pairs with the Carrick MCP server, which lets agents search functions by intent rather than name.",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.129",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Carrick",
|
|
7
7
|
"email": "hello@carrick.tools"
|
|
@@ -1093,9 +1093,13 @@ function paramLocatorHints(request) {
|
|
|
1093
1093
|
* node unchanged. The mirror of the v1 inferrer's `unwrapJsonStringifyArg`:
|
|
1094
1094
|
* the global serialiser is identified by the standard `JSON` object, the one
|
|
1095
1095
|
* name every runtime shares.
|
|
1096
|
+
*
|
|
1097
|
+
* carrick#2010: a property whose value is the serialiser call (`body:
|
|
1098
|
+
* JSON.stringify(...)`, the node the line fallback prefers on that line) is
|
|
1099
|
+
* read through to the call, and so to its argument.
|
|
1096
1100
|
*/
|
|
1097
1101
|
function serialisedArgument(node) {
|
|
1098
|
-
let current = node;
|
|
1102
|
+
let current = ts.isPropertyAssignment(node) ? node.initializer : node;
|
|
1099
1103
|
while (ts.isParenthesizedExpression(current))
|
|
1100
1104
|
current = current.expression;
|
|
1101
1105
|
if (ts.isCallExpression(current) &&
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
* assignment error, sent union taken in part by a weak expected type
|
|
18
18
|
* -> unverifiable (carrick#1995)
|
|
19
19
|
* assignment error on the published type that the sent side's unwidened
|
|
20
|
-
* reading does not repeat -> producer_wider (carrick#1538)
|
|
20
|
+
* reading does not repeat -> producer_wider (carrick#1538),
|
|
21
|
+
* or compatible with a note when
|
|
22
|
+
* the consumer sends (carrick#2011)
|
|
21
23
|
* assignment-class error -> incompatible
|
|
22
24
|
* no diagnostics -> compatible [lowest precedence]
|
|
23
25
|
*
|
|
@@ -87,3 +89,8 @@ export interface ClassifyInput {
|
|
|
87
89
|
}
|
|
88
90
|
/** Classify one pair into exactly one bucket, honouring the precedence order. */
|
|
89
91
|
export declare function classifyPair(input: ClassifyInput): CheckVerdict;
|
|
92
|
+
/**
|
|
93
|
+
* The note on a request the consumer's unwidened reading cleared
|
|
94
|
+
* (carrick#2011).
|
|
95
|
+
*/
|
|
96
|
+
export declare const CONSUMER_WIDER_NOTE: string;
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
* assignment error, sent union taken in part by a weak expected type
|
|
18
18
|
* -> unverifiable (carrick#1995)
|
|
19
19
|
* assignment error on the published type that the sent side's unwidened
|
|
20
|
-
* reading does not repeat -> producer_wider (carrick#1538)
|
|
20
|
+
* reading does not repeat -> producer_wider (carrick#1538),
|
|
21
|
+
* or compatible with a note when
|
|
22
|
+
* the consumer sends (carrick#2011)
|
|
21
23
|
* assignment-class error -> incompatible
|
|
22
24
|
* no diagnostics -> compatible [lowest precedence]
|
|
23
25
|
*
|
|
@@ -277,7 +279,19 @@ export function classifyPair(input) {
|
|
|
277
279
|
// return read with no literal widened fits what the other side expects,
|
|
278
280
|
// so what travels agrees and only the published type is wider. Its own
|
|
279
281
|
// bucket, which carries no diagnostic: a reason is read as a mismatch.
|
|
282
|
+
// carrick#2011: the same for a request body, where the consumer sends
|
|
283
|
+
// and its body was read with the literals the call writes kept. A
|
|
284
|
+
// consumer has no class of its own on the wire, so the pair is the
|
|
285
|
+
// compatible it is, and a note says the published type is wider.
|
|
280
286
|
if (assignDiag && unwidenedReadingFits(input)) {
|
|
287
|
+
if (plan.direction.sent === 'consumer') {
|
|
288
|
+
return {
|
|
289
|
+
...base,
|
|
290
|
+
bucket: 'compatible',
|
|
291
|
+
notes: [...base.notes, CONSUMER_WIDER_NOTE],
|
|
292
|
+
...factness(input),
|
|
293
|
+
};
|
|
294
|
+
}
|
|
281
295
|
return { ...base, bucket: 'producer_wider', ...factness(input) };
|
|
282
296
|
}
|
|
283
297
|
if (assignDiag) {
|
|
@@ -337,6 +351,12 @@ export function classifyPair(input) {
|
|
|
337
351
|
// 6. No diagnostics -> compatible.
|
|
338
352
|
return { ...base, bucket: 'compatible', ...factness(input) };
|
|
339
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* The note on a request the consumer's unwidened reading cleared
|
|
356
|
+
* (carrick#2011).
|
|
357
|
+
*/
|
|
358
|
+
export const CONSUMER_WIDER_NOTE = "the consumer's published request type is wider than what the call sends: " +
|
|
359
|
+
'it widened a literal the call writes, and the values sent fit the producer';
|
|
340
360
|
function onUnwidenedLines(plan, diagnostic) {
|
|
341
361
|
return plan.unwidenedFromLine !== undefined && diagnostic.line >= plan.unwidenedFromLine;
|
|
342
362
|
}
|
|
@@ -136,11 +136,11 @@ export declare function decisiveAssignmentLine(plan: ProbePlan): number;
|
|
|
136
136
|
* the classifier never depends on hard-coded offsets. `packageOf` maps a
|
|
137
137
|
* service name to its workspace package specifier (e.g. `@carrick/orders`).
|
|
138
138
|
*
|
|
139
|
-
* `unwidenedAliasFor` answers, for
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
* probe is what it always was, byte
|
|
144
|
-
*
|
|
139
|
+
* `unwidenedAliasFor` answers, for the sending side, the surface export that
|
|
140
|
+
* carries its unwidened reading, when its stub ships one: a producer's
|
|
141
|
+
* response (carrick#1538) or a consumer's request body (carrick#2011). The
|
|
142
|
+
* probe of an `http` pair then ends with a second assignment of that reading,
|
|
143
|
+
* in the wire form. Without an answer the probe is what it always was, byte
|
|
144
|
+
* for byte.
|
|
145
145
|
*/
|
|
146
|
-
export declare function buildProbe(spec: CheckPairSpec, packageOf: (serviceName: string) => string, unwidenedAliasFor?: (
|
|
146
|
+
export declare function buildProbe(spec: CheckPairSpec, packageOf: (serviceName: string) => string, unwidenedAliasFor?: (sent: CheckPairEndpoint) => string | undefined): ProbePlan;
|
|
@@ -126,12 +126,12 @@ export function decisiveAssignmentLine(plan) {
|
|
|
126
126
|
* the classifier never depends on hard-coded offsets. `packageOf` maps a
|
|
127
127
|
* service name to its workspace package specifier (e.g. `@carrick/orders`).
|
|
128
128
|
*
|
|
129
|
-
* `unwidenedAliasFor` answers, for
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
* probe is what it always was, byte
|
|
134
|
-
*
|
|
129
|
+
* `unwidenedAliasFor` answers, for the sending side, the surface export that
|
|
130
|
+
* carries its unwidened reading, when its stub ships one: a producer's
|
|
131
|
+
* response (carrick#1538) or a consumer's request body (carrick#2011). The
|
|
132
|
+
* probe of an `http` pair then ends with a second assignment of that reading,
|
|
133
|
+
* in the wire form. Without an answer the probe is what it always was, byte
|
|
134
|
+
* for byte.
|
|
135
135
|
*/
|
|
136
136
|
export function buildProbe(spec, packageOf, unwidenedAliasFor) {
|
|
137
137
|
const id = pairId(spec);
|
|
@@ -319,15 +319,14 @@ export function buildProbe(spec, packageOf, unwidenedAliasFor) {
|
|
|
319
319
|
// type or a mismatch here says only that the second reading did not clear
|
|
320
320
|
// the pair, and the verdict on the published type stands.
|
|
321
321
|
//
|
|
322
|
-
// Only an `http`
|
|
323
|
-
//
|
|
324
|
-
//
|
|
325
|
-
//
|
|
326
|
-
//
|
|
322
|
+
// Only an `http` pair gets one: a response the producer sends, or a request
|
|
323
|
+
// body the consumer sends (carrick#2011), each judged on a decisive
|
|
324
|
+
// assignment the second reading mirrors, here in the wire form. A GraphQL
|
|
325
|
+
// pair compares an unwrapped comparand (above), which a plain assignment of
|
|
326
|
+
// the reading would not mirror. Socket and pub/sub payloads are not read
|
|
327
|
+
// again.
|
|
327
328
|
let unwidenedFromLine;
|
|
328
|
-
const sentUnwidenedAlias =
|
|
329
|
-
? unwidenedAliasFor?.(sentEndpoint)
|
|
330
|
-
: undefined;
|
|
329
|
+
const sentUnwidenedAlias = spec.protocol === 'http' ? unwidenedAliasFor?.(sentEndpoint) : undefined;
|
|
331
330
|
if (sentUnwidenedAlias !== undefined) {
|
|
332
331
|
const local = UNWIDENED_LOCAL_NAME;
|
|
333
332
|
unwidenedFromLine = push(`import type { ${sentUnwidenedAlias} as ${local} } from '${sentPkg}';`);
|
|
@@ -388,17 +388,17 @@ function readStubAliasRecords(stubs) {
|
|
|
388
388
|
return byService;
|
|
389
389
|
}
|
|
390
390
|
/**
|
|
391
|
-
* The unwidened reading a
|
|
392
|
-
* (carrick#1538), as `buildProbe` asks for it. Read from the same manifest the
|
|
391
|
+
* The unwidened reading a sending side's stub ships beside one of its aliases
|
|
392
|
+
* (carrick#1538, carrick#2011), as `buildProbe` asks for it. Read from the same manifest the
|
|
393
393
|
* pre-gate reads. A reading the capture already found a member-level
|
|
394
394
|
* `any`/`unknown` in is not offered: it would assign to whatever the other
|
|
395
395
|
* side declares.
|
|
396
396
|
*/
|
|
397
397
|
function unwidenedAliasIn(aliasRecords) {
|
|
398
|
-
return (
|
|
398
|
+
return (sent) => {
|
|
399
399
|
const record = aliasRecords
|
|
400
|
-
.get(
|
|
401
|
-
?.get(unwidenedAliasOf(
|
|
400
|
+
.get(sent.service_name)
|
|
401
|
+
?.get(unwidenedAliasOf(sent.alias));
|
|
402
402
|
if (!record || record.any_provenance?.length)
|
|
403
403
|
return undefined;
|
|
404
404
|
return record.alias;
|
|
@@ -26,6 +26,7 @@ import { DefinitionResolver } from './definition-resolver.js';
|
|
|
26
26
|
import { captureStub, findDisqualifyingTopTypes, jsonWireDeclarations, runCheck, } from './capture/index.js';
|
|
27
27
|
import { Retyper } from './retype.js';
|
|
28
28
|
import { LibraryClaimsVerifier, httpCheck } from './library-claims.js';
|
|
29
|
+
import { readServerLabels } from './server-labels.js';
|
|
29
30
|
import { PROGRESS_INTERVAL_MS, atMostEvery } from './progress.js';
|
|
30
31
|
import { mergeInferTimings } from './infer-timing.js';
|
|
31
32
|
import { addProgramFiles, listProgramFiles } from './program-files.js';
|
|
@@ -108,6 +109,7 @@ function projectComponents(key = '') {
|
|
|
108
109
|
packageDirectoryOf: (file) => loader.packageDirectoryOf(file),
|
|
109
110
|
resolveModule: (name, from, options) => loader.resolveThroughGraph(name, from, options),
|
|
110
111
|
}),
|
|
112
|
+
labelledMembers: new Map(),
|
|
111
113
|
};
|
|
112
114
|
components.set(key, built);
|
|
113
115
|
}
|
|
@@ -337,10 +339,13 @@ function handleInfer(request) {
|
|
|
337
339
|
// One count for the request, whichever programs its items span.
|
|
338
340
|
let done = 0;
|
|
339
341
|
const report = atMostEvery(PROGRESS_INTERVAL_MS, () => writeProgress(request.request_id, 'infer', `${done} of ${request.requests.length}`));
|
|
340
|
-
const results = [...byProject(request.requests, (item) => item.file_path)].map(([key, items]) =>
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
342
|
+
const results = [...byProject(request.requests, (item) => item.file_path)].map(([key, items]) => {
|
|
343
|
+
const built = projectComponents(key);
|
|
344
|
+
return built.typeInferrer.infer(items, request.extraction_config, () => {
|
|
345
|
+
done += 1;
|
|
346
|
+
report();
|
|
347
|
+
}, request.model_symbols, labelledMembersFor(built, key, items, request.server_claims));
|
|
348
|
+
});
|
|
344
349
|
const result = results.length === 1
|
|
345
350
|
? results[0]
|
|
346
351
|
: (() => {
|
|
@@ -372,6 +377,40 @@ function handleInfer(request) {
|
|
|
372
377
|
};
|
|
373
378
|
}
|
|
374
379
|
}
|
|
380
|
+
/**
|
|
381
|
+
* How long reading one program's server-framework labels may take: as
|
|
382
|
+
* long as a verify_library_claims request, since the reading builds a
|
|
383
|
+
* program of its own. Labels it does not reach are not read.
|
|
384
|
+
*/
|
|
385
|
+
const SERVER_CLAIMS_BUDGET_MS = 600_000;
|
|
386
|
+
/** The infer kinds a route row asks: only these read a handler's parameters (carrick#2674). */
|
|
387
|
+
const ROUTE_ROW_KINDS = new Set(['response_body', 'request_body']);
|
|
388
|
+
/**
|
|
389
|
+
* carrick#2674: the members an `infer` request's server-framework claims
|
|
390
|
+
* name, verified again in a program of their own beside the inferrer's for
|
|
391
|
+
* `key` (`readServerLabels`). Undefined when the request carries none, or
|
|
392
|
+
* the group asks no route row, so the inferrer reads nothing new. Read once
|
|
393
|
+
* per program and claims.
|
|
394
|
+
*/
|
|
395
|
+
function labelledMembersFor(built, key, items, claims) {
|
|
396
|
+
if (!claims || claims.checks.length === 0)
|
|
397
|
+
return undefined;
|
|
398
|
+
if (!items.some((item) => ROUTE_ROW_KINDS.has(item.infer_kind)))
|
|
399
|
+
return undefined;
|
|
400
|
+
const cacheKey = JSON.stringify(claims);
|
|
401
|
+
let labels = built.labelledMembers.get(cacheKey);
|
|
402
|
+
if (!labels) {
|
|
403
|
+
const loader = initializedLoader();
|
|
404
|
+
labels = readServerLabels({
|
|
405
|
+
getRepoRoot: () => loader.getRepoRoot(),
|
|
406
|
+
scriptProjectFor: (owner) => loader.scriptProjectFor(owner),
|
|
407
|
+
packageDirectoryOf: (file) => loader.packageDirectoryOf(file),
|
|
408
|
+
resolveModule: (name, from, options) => loader.resolveThroughGraph(name, from, options),
|
|
409
|
+
}, key, claims, SERVER_CLAIMS_BUDGET_MS, log);
|
|
410
|
+
built.labelledMembers.set(cacheKey, labels);
|
|
411
|
+
}
|
|
412
|
+
return labels;
|
|
413
|
+
}
|
|
375
414
|
/**
|
|
376
415
|
* How long one retype_check request may spend before the items it has not
|
|
377
416
|
* reached abstain: well inside the scanner's 900s read deadline.
|
|
@@ -37,7 +37,25 @@
|
|
|
37
37
|
*/
|
|
38
38
|
import { ts, type Project } from 'ts-morph';
|
|
39
39
|
import { type PackageDirectoryOf } from './position-rows.js';
|
|
40
|
-
import type { LibraryCheck, LibrarySurface, SemanticsCheck, SemanticsModule, SemanticsResult } from './types.js';
|
|
40
|
+
import type { ClaimSlot, LibraryCheck, LibrarySurface, SemanticsCheck, SemanticsModule, SemanticsDeclaration, SemanticsResult } from './types.js';
|
|
41
|
+
/** How one check came out, before it is stamped with its claim and receiver. */
|
|
42
|
+
type Outcome = {
|
|
43
|
+
verdict: 'verified';
|
|
44
|
+
declarations?: DeclaredAt[];
|
|
45
|
+
/**
|
|
46
|
+
* In-process only, never stamped onto a verdict: the declarations of
|
|
47
|
+
* the member a verified op calls, and, for a receive op whose
|
|
48
|
+
* `request` names a `body`, of the member that path ends on
|
|
49
|
+
* (carrick#2674). Read by `labelledMembers`.
|
|
50
|
+
*/
|
|
51
|
+
members?: readonly ts.Declaration[];
|
|
52
|
+
bodyMembers?: readonly ts.Declaration[];
|
|
53
|
+
} | {
|
|
54
|
+
verdict: 'failed' | 'unchecked';
|
|
55
|
+
reason: string;
|
|
56
|
+
};
|
|
57
|
+
/** Where a member is declared, spelled as a position row's `decl_file` and `decl_line`. */
|
|
58
|
+
type DeclaredAt = SemanticsDeclaration;
|
|
41
59
|
export interface VerifyResult {
|
|
42
60
|
semantics: SemanticsResult[];
|
|
43
61
|
modules: SemanticsModule[];
|
|
@@ -78,7 +96,15 @@ export declare class LibraryClaimsVerifier {
|
|
|
78
96
|
* A check on an instance or a scope reads the maker or scope claims of the
|
|
79
97
|
* same request first, whatever their place in it.
|
|
80
98
|
*/
|
|
81
|
-
run(fromDir: string, checks: LibraryCheck[], budgetMs: number, scanRoot?: string): VerifyResult;
|
|
99
|
+
run(fromDir: string, checks: LibraryCheck[], budgetMs: number, scanRoot?: string, options?: RunOptions): VerifyResult;
|
|
100
|
+
/**
|
|
101
|
+
* The members a service's server-framework labels name, read with the
|
|
102
|
+
* verifier itself so only a label that verifies in the service's own
|
|
103
|
+
* program counts (carrick#2674): each verified `send` op that carries a
|
|
104
|
+
* `payload` slot, and each verified `receive` op whose `request` names a
|
|
105
|
+
* `body` path. Other checks are not judged.
|
|
106
|
+
*/
|
|
107
|
+
labelledMembers(fromDir: string, checks: LibraryCheck[], budgetMs: number, scanRoot?: string, typePackages?: Readonly<Record<string, readonly string[]>>): LabelledMembers;
|
|
82
108
|
/**
|
|
83
109
|
* Each specifier's declared surface, read with the verifier's predicates
|
|
84
110
|
* (carrick#1660): every value export (or only those `only` names for the
|
|
@@ -114,7 +140,41 @@ export interface ListedSurface {
|
|
|
114
140
|
* array of `[package, exports]` for every surface that listed at least one
|
|
115
141
|
* export, sorted by `package` (code unit order). A specifier that lists
|
|
116
142
|
* nothing (unresolved, local, no value exports) is left out, so asking for a
|
|
117
|
-
* subpath a version does not have changes nothing.
|
|
143
|
+
* subpath a version does not have changes nothing. Handler members are not
|
|
144
|
+
* hashed. Type text already names
|
|
118
145
|
* the request's directory as `<root>`.
|
|
119
146
|
*/
|
|
120
147
|
export declare function fullSurfaceSha256(surfaces: readonly LibrarySurface[]): string;
|
|
148
|
+
/** What `run` reads beyond the checks; none of it is part of a verdict. */
|
|
149
|
+
interface RunOptions {
|
|
150
|
+
/** Called with each check's outcome, in request order. */
|
|
151
|
+
observe?: (check: LibraryCheck, outcome: Outcome) => void;
|
|
152
|
+
/** Read server `send` ops as replies (`SERVER_REPLY_RULES`). */
|
|
153
|
+
readReplies?: boolean;
|
|
154
|
+
/**
|
|
155
|
+
* Per package specifier, the type-only packages the store says its surface
|
|
156
|
+
* re-exports (carrick#2674): a member one of them declares is the
|
|
157
|
+
* package's own, as the store reads it.
|
|
158
|
+
*/
|
|
159
|
+
typePackages?: Readonly<Record<string, readonly string[]>>;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* A declaration's key within one process: its file as the compiler names it
|
|
163
|
+
* and its start. Two programs of one project name a declaration alike, so a
|
|
164
|
+
* label read in the verifier's probe program joins a member read in the
|
|
165
|
+
* inferrer's (carrick#2674).
|
|
166
|
+
*/
|
|
167
|
+
export declare function declarationKey(declaration: ts.Node): string;
|
|
168
|
+
/**
|
|
169
|
+
* The members a service's verified server-framework labels name, by
|
|
170
|
+
* {@link declarationKey} (carrick#2674): each `send` op member with the slot
|
|
171
|
+
* its payload sits in, and each member a receive op's `request.body` path
|
|
172
|
+
* ends on.
|
|
173
|
+
*/
|
|
174
|
+
export interface LabelledMembers {
|
|
175
|
+
sends: ReadonlyMap<string, ClaimSlot>;
|
|
176
|
+
bodies: ReadonlySet<string>;
|
|
177
|
+
/** How each label read came out (`verified`, or the reason it was not), for the log. */
|
|
178
|
+
outcomes?: Readonly<Record<string, number>>;
|
|
179
|
+
}
|
|
180
|
+
export {};
|