carrick 0.3.105 → 0.3.106
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.d.ts +7 -0
- package/sidecar/dist/src/capture/anchors.js +151 -24
- package/sidecar/dist/src/capture/api.d.ts +42 -1
- package/sidecar/dist/src/capture/check-classify.d.ts +9 -1
- package/sidecar/dist/src/capture/check-classify.js +15 -0
- package/sidecar/dist/src/capture/check.js +13 -1
- package/sidecar/dist/src/capture/index.js +8 -0
- package/sidecar/dist/src/capture/self-check.js +9 -0
- package/sidecar/dist/src/capture/service-config.d.ts +2 -0
- package/sidecar/dist/src/capture/service-config.js +1 -1
- package/sidecar/dist/src/failure-path.d.ts +34 -3
- package/sidecar/dist/src/failure-path.js +59 -35
- package/sidecar/dist/src/printed-names.d.ts +43 -0
- package/sidecar/dist/src/printed-names.js +186 -0
- package/sidecar/dist/src/retype.js +57 -109
- package/sidecar/dist/src/type-inferrer.d.ts +33 -3
- package/sidecar/dist/src/type-inferrer.js +191 -13
- package/sidecar/dist/src/type-structural-expander.js +10 -1
- package/sidecar/dist/src/types.d.ts +24 -0
- package/sidecar/dist/src/validators.d.ts +76 -0
- package/sidecar/dist/src/validators.js +8 -0
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
import * as path from 'node:path';
|
|
21
21
|
import { Node, SyntaxKind, ts, } from 'ts-morph';
|
|
22
22
|
import { validateInferRequestItem } from './validators.js';
|
|
23
|
+
import { notePrintedType, PrintedTypes } from './printed-names.js';
|
|
23
24
|
import { externalImportsOf, isExternalOrigin } from './origin.js';
|
|
24
25
|
import { reachedOnlyOnFailure } from './failure-path.js';
|
|
25
26
|
import { addedDiagnostics, applyInsertions, fileDiagnostics, literalInsertions, mapBack, mapForward, normalise, pathOf, } from './unwidened.js';
|
|
@@ -220,6 +221,14 @@ const REQUEST_BODY_PARTS = new Set(['json', 'form', 'body']);
|
|
|
220
221
|
* these names; a type parameter alone also types response modes and fallbacks.
|
|
221
222
|
*/
|
|
222
223
|
const BODY_MEMBER_NAMES = new Set(['data', 'body', 'json']);
|
|
224
|
+
/**
|
|
225
|
+
* The zero-argument reads that take the WHOLE body out of a transport response
|
|
226
|
+
* (the platform `Response` and the clients that copy its shape): parsed as
|
|
227
|
+
* JSON, or as raw text (carrick#1842).
|
|
228
|
+
*/
|
|
229
|
+
const WHOLE_BODY_READS = new Set(['json', 'text']);
|
|
230
|
+
/** The body format a caller names to read a response as raw text (carrick#1842). */
|
|
231
|
+
const RAW_TEXT_FORMAT = 'text';
|
|
223
232
|
/**
|
|
224
233
|
* Print a `Type` to its string form WITHOUT the compiler's default truncation.
|
|
225
234
|
*
|
|
@@ -230,7 +239,18 @@ const BODY_MEMBER_NAMES = new Set(['data', 'body', 'json']);
|
|
|
230
239
|
*/
|
|
231
240
|
const TYPE_TEXT_FLAGS = ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.InTypeAlias;
|
|
232
241
|
function typeText(type, enclosingNode) {
|
|
233
|
-
|
|
242
|
+
const text = type.getText(enclosingNode, TYPE_TEXT_FLAGS);
|
|
243
|
+
notePrintedType(type, enclosingNode, text);
|
|
244
|
+
return text;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* `text` is `string`, alone or beside `null` and `undefined` in either order:
|
|
248
|
+
* the only payload a raw-text read publishes (carrick#1842).
|
|
249
|
+
*/
|
|
250
|
+
function isBareStringText(text) {
|
|
251
|
+
const members = text.split('|').map((member) => member.trim());
|
|
252
|
+
return (members.includes('string') &&
|
|
253
|
+
members.every((member) => member === 'string' || member === 'null' || member === 'undefined'));
|
|
234
254
|
}
|
|
235
255
|
/**
|
|
236
256
|
* How long the unwidened reading of one batch may take by default. The
|
|
@@ -310,8 +330,14 @@ export class TypeInferrer {
|
|
|
310
330
|
errors.push(`Invalid infer item at ${request.file_path}:${loc} (${request.infer_kind}): ${itemError}`);
|
|
311
331
|
continue;
|
|
312
332
|
}
|
|
313
|
-
|
|
333
|
+
// carrick#1836: what the names the published text prints meant, read
|
|
334
|
+
// while the program the prints were made in is still the project's.
|
|
335
|
+
// The unwidened re-read below records nothing: it prints the same
|
|
336
|
+
// node, and its reading has a budget.
|
|
337
|
+
const prints = new PrintedTypes();
|
|
338
|
+
const result = prints.during(() => this.inferSingle(request, extractionConfig));
|
|
314
339
|
if (result) {
|
|
340
|
+
this.recordPrintedNames(result, request, prints);
|
|
315
341
|
inferredTypes.push(result);
|
|
316
342
|
if (request.infer_kind === 'response_body' || request.infer_kind === 'function_return') {
|
|
317
343
|
responses.push({ request, result });
|
|
@@ -341,6 +367,18 @@ export class TypeInferrer {
|
|
|
341
367
|
errors: errors.length > 0 ? errors : undefined,
|
|
342
368
|
};
|
|
343
369
|
}
|
|
370
|
+
/**
|
|
371
|
+
* carrick#1836: list on `result` the declarations behind the names its text
|
|
372
|
+
* prints that the request's file cannot resolve (`PrintedTypes.namesIn`).
|
|
373
|
+
*/
|
|
374
|
+
recordPrintedNames(result, request, prints) {
|
|
375
|
+
const sourceFile = this.getSourceFile(request.file_path);
|
|
376
|
+
if (!sourceFile)
|
|
377
|
+
return;
|
|
378
|
+
const printedNames = prints.namesIn([result.type_string], sourceFile.compilerNode, this.project.getTypeChecker().compilerObject);
|
|
379
|
+
if (printedNames.length > 0)
|
|
380
|
+
result.printed_names = printedNames;
|
|
381
|
+
}
|
|
344
382
|
/**
|
|
345
383
|
* carrick#1516: read each response inference again with the literals on its
|
|
346
384
|
* handler's path marked `as const`, and record the narrower type the handler
|
|
@@ -1209,16 +1247,55 @@ export class TypeInferrer {
|
|
|
1209
1247
|
const carrierCandidate = unwrapResult.wasUnwrapped || explicitType
|
|
1210
1248
|
? undefined
|
|
1211
1249
|
: this.resultCarrierPayload(returnType, terminalNode, use.projections, `${request.file_path}:${request.line_number}`);
|
|
1250
|
+
// carrick#1841: what the carrier holds goes through the service's wrapper
|
|
1251
|
+
// rules before it is published, as the call's own result did. The carrier
|
|
1252
|
+
// is found by its shape, so what it holds can still be a library's
|
|
1253
|
+
// envelope: a request library answers `Task<Outcome<Reply<T>, E>>`, and
|
|
1254
|
+
// `Reply<T>` is that library's response object, a status, a url and
|
|
1255
|
+
// headers around the body. Where a rule reads a payload out of it, that
|
|
1256
|
+
// payload is the body. Where a rule verifies it as the library's transport
|
|
1257
|
+
// and reads nothing out of it, this site states no contract, and the
|
|
1258
|
+
// transport object must not stand in for one: judged against a
|
|
1259
|
+
// producer's body, every member it adds reads as a field the producer
|
|
1260
|
+
// does not send.
|
|
1261
|
+
//
|
|
1262
|
+
// The abstain is decided, so it rides the row (`machinery_envelope` at the
|
|
1263
|
+
// root, no anchor). A plain `null` is re-read by the capture's own
|
|
1264
|
+
// locator, which would resolve the raw call and publish the carrier.
|
|
1265
|
+
const carrierUnwrap = carrierCandidate
|
|
1266
|
+
? this.unwrapTypeWithConfig(carrierCandidate, terminalNode, extractionConfig)
|
|
1267
|
+
: undefined;
|
|
1268
|
+
if (carrierCandidate &&
|
|
1269
|
+
carrierUnwrap?.wasUnwrapped &&
|
|
1270
|
+
carrierUnwrap.typeString.trim() === 'unknown') {
|
|
1271
|
+
const carried = typeText(carrierCandidate, terminalNode);
|
|
1272
|
+
this.log(`Call result at ${request.file_path}:${request.line_number} carries ${carried}, which ` +
|
|
1273
|
+
"the service's wrapper rules verify as transport and read no payload out of; this " +
|
|
1274
|
+
'site states no response contract');
|
|
1275
|
+
const abstain = this.createInferredType(request, 'unknown', false, this.getNodeLocation(callExpr));
|
|
1276
|
+
abstain.any_provenance = [
|
|
1277
|
+
{
|
|
1278
|
+
path: '',
|
|
1279
|
+
kind: 'unknown',
|
|
1280
|
+
reason: 'machinery_envelope',
|
|
1281
|
+
detail: "what this call's result carries is transport that the service's wrapper rules " +
|
|
1282
|
+
'verify and read no payload out of (a library response object around the body), ' +
|
|
1283
|
+
'so this site states no response contract',
|
|
1284
|
+
},
|
|
1285
|
+
];
|
|
1286
|
+
return abstain;
|
|
1287
|
+
}
|
|
1288
|
+
const carried = carrierUnwrap?.wasUnwrapped && carrierUnwrap.payloadType
|
|
1289
|
+
? carrierUnwrap.payloadType
|
|
1290
|
+
: carrierCandidate;
|
|
1212
1291
|
// The payload rides the row as its own MEMBERS, never as its bare name
|
|
1213
1292
|
// (#257): `derive_capture_anchors` turns a usable inference into a literal
|
|
1214
1293
|
// capture anchor, and a bare name is out of scope where the surface
|
|
1215
1294
|
// declares the alias, so it would decay to a top type and publish nothing
|
|
1216
1295
|
// — trading a wrong answer for no answer. Where the payload carries no
|
|
1217
1296
|
// member shape to print, the carrier keeps its own answer.
|
|
1218
|
-
const carrierText =
|
|
1219
|
-
|
|
1220
|
-
: null;
|
|
1221
|
-
const carrierPayload = carrierText ? carrierCandidate : undefined;
|
|
1297
|
+
const carrierText = carried ? this.structuralTextFromType(carried, terminalNode) : null;
|
|
1298
|
+
const carrierPayload = carrierText ? carried : undefined;
|
|
1222
1299
|
if (carrierPayload && carrierText) {
|
|
1223
1300
|
typeString = carrierText;
|
|
1224
1301
|
}
|
|
@@ -1346,8 +1423,101 @@ export class TypeInferrer {
|
|
|
1346
1423
|
if (statedBody) {
|
|
1347
1424
|
inferred.stated_body = statedBody;
|
|
1348
1425
|
}
|
|
1426
|
+
// carrick#1842: `string` cannot tell a body read as raw text from a JSON
|
|
1427
|
+
// body that is a string, and raw text states no structural contract. The
|
|
1428
|
+
// row says which it is, so the check phase can read the pair unverifiable
|
|
1429
|
+
// instead of comparing `string` with the other side's body.
|
|
1430
|
+
if (isBareStringText(typeString) &&
|
|
1431
|
+
(this.textReadAtTerminal(callExpr, terminalNode) || this.callChoosesTextBody(callExpr))) {
|
|
1432
|
+
inferred.raw_text_read = true;
|
|
1433
|
+
}
|
|
1349
1434
|
return inferred;
|
|
1350
1435
|
}
|
|
1436
|
+
/**
|
|
1437
|
+
* The terminal of a call's def-use walk is a zero-argument `.text()` read of
|
|
1438
|
+
* the call's own result (carrick#1842): on its binding (`res.text()`,
|
|
1439
|
+
* through a declaration, `await` or a cast), or in the callback a `then` on
|
|
1440
|
+
* the call hands the response to (`fetch(u).then((res) => res.text())`).
|
|
1441
|
+
*/
|
|
1442
|
+
textReadAtTerminal(callExpr, terminal) {
|
|
1443
|
+
const value = Node.isVariableDeclaration(terminal) ? terminal.getInitializer() : terminal;
|
|
1444
|
+
const read = value ? this.unwrapExpressionNode(value) : undefined;
|
|
1445
|
+
if (!read || !Node.isCallExpression(read))
|
|
1446
|
+
return false;
|
|
1447
|
+
const callResult = this.unwrapPromiseType(callExpr.getType()).compilerType;
|
|
1448
|
+
if (this.isTextReadOf(read, (receiver) => receiver === callExpr ||
|
|
1449
|
+
this.unwrapPromiseType(receiver.getType()).compilerType === callResult)) {
|
|
1450
|
+
return true;
|
|
1451
|
+
}
|
|
1452
|
+
const then = read.getExpression();
|
|
1453
|
+
if (!Node.isPropertyAccessExpression(then) ||
|
|
1454
|
+
then.getName() !== 'then' ||
|
|
1455
|
+
this.unwrapExpressionNode(then.getExpression()) !== callExpr) {
|
|
1456
|
+
return false;
|
|
1457
|
+
}
|
|
1458
|
+
const callback = read.getArguments()[0];
|
|
1459
|
+
if (!callback || (!Node.isArrowFunction(callback) && !Node.isFunctionExpression(callback))) {
|
|
1460
|
+
return false;
|
|
1461
|
+
}
|
|
1462
|
+
const param = callback.getParameters()[0]?.getNameNode();
|
|
1463
|
+
if (!param || !Node.isIdentifier(param))
|
|
1464
|
+
return false;
|
|
1465
|
+
const returned = this.returnedExpressions(callback);
|
|
1466
|
+
const inner = returned.length === 1 ? this.unwrapExpressionNode(returned[0]) : undefined;
|
|
1467
|
+
return (!!inner &&
|
|
1468
|
+
Node.isCallExpression(inner) &&
|
|
1469
|
+
this.isTextReadOf(inner, (receiver) => Node.isIdentifier(receiver) && receiver.getSymbol() === param.getSymbol()));
|
|
1470
|
+
}
|
|
1471
|
+
/** `call` is `<receiver>.text()` with no arguments, and `accept` takes its receiver. */
|
|
1472
|
+
isTextReadOf(call, accept) {
|
|
1473
|
+
const access = call.getExpression();
|
|
1474
|
+
return (Node.isPropertyAccessExpression(access) &&
|
|
1475
|
+
access.getName() === RAW_TEXT_FORMAT &&
|
|
1476
|
+
call.getArguments().length === 0 &&
|
|
1477
|
+
accept(this.unwrapExpressionNode(access.getExpression())));
|
|
1478
|
+
}
|
|
1479
|
+
/**
|
|
1480
|
+
* The call's resolved signature, at this site, types a member of an object
|
|
1481
|
+
* argument as exactly the literal `'text'`, and the source passes that
|
|
1482
|
+
* literal there (carrick#1842). That is how a request library lets a caller
|
|
1483
|
+
* choose a text body from the formats it offers (`{ type: 'text' }`): a
|
|
1484
|
+
* generic config instantiated by the literal, or an overload taken by it.
|
|
1485
|
+
* A member typed as a wider union (`kind: 'text' | 'image'`) chooses no
|
|
1486
|
+
* format, and no member name is read.
|
|
1487
|
+
*/
|
|
1488
|
+
callChoosesTextBody(callExpr) {
|
|
1489
|
+
const checker = this.project.getTypeChecker().compilerObject;
|
|
1490
|
+
let signature;
|
|
1491
|
+
try {
|
|
1492
|
+
signature = checker.getResolvedSignature(callExpr.compilerNode);
|
|
1493
|
+
}
|
|
1494
|
+
catch {
|
|
1495
|
+
return false;
|
|
1496
|
+
}
|
|
1497
|
+
if (!signature || signature.parameters.length === 0)
|
|
1498
|
+
return false;
|
|
1499
|
+
return callExpr.getArguments().some((argument, index) => {
|
|
1500
|
+
if (!Node.isObjectLiteralExpression(argument))
|
|
1501
|
+
return false;
|
|
1502
|
+
const parameter = signature.parameters[Math.min(index, signature.parameters.length - 1)];
|
|
1503
|
+
const parameterType = checker.getTypeOfSymbolAtLocation(parameter, callExpr.compilerNode);
|
|
1504
|
+
return argument.getProperties().some((property) => {
|
|
1505
|
+
if (!Node.isPropertyAssignment(property))
|
|
1506
|
+
return false;
|
|
1507
|
+
const value = property.getInitializer();
|
|
1508
|
+
if (!value ||
|
|
1509
|
+
!(Node.isStringLiteral(value) || Node.isNoSubstitutionTemplateLiteral(value)) ||
|
|
1510
|
+
value.getLiteralValue() !== RAW_TEXT_FORMAT) {
|
|
1511
|
+
return false;
|
|
1512
|
+
}
|
|
1513
|
+
const member = checker.getPropertyOfType(parameterType, property.getName());
|
|
1514
|
+
if (!member)
|
|
1515
|
+
return false;
|
|
1516
|
+
const declared = checker.getNonNullableType(checker.getTypeOfSymbolAtLocation(member, callExpr.compilerNode));
|
|
1517
|
+
return declared.isStringLiteral() && declared.value === RAW_TEXT_FORMAT;
|
|
1518
|
+
});
|
|
1519
|
+
});
|
|
1520
|
+
}
|
|
1351
1521
|
/**
|
|
1352
1522
|
* What the source states the body read at `terminal` to be, when the type
|
|
1353
1523
|
* `extractExplicitTypeFromAncestor` printed for it is stated AT the read
|
|
@@ -1459,10 +1629,12 @@ export class TypeInferrer {
|
|
|
1459
1629
|
symbol = symbol.getAliasedSymbol() ?? symbol;
|
|
1460
1630
|
}
|
|
1461
1631
|
const source = symbol?.getDeclarations()[0]?.getSourceFile().getFilePath();
|
|
1632
|
+
const typeArguments = node.getTypeArguments().length;
|
|
1462
1633
|
return {
|
|
1463
1634
|
root: nameNode.getText(),
|
|
1464
1635
|
...(source ? { root_source: source } : {}),
|
|
1465
1636
|
...depthField,
|
|
1637
|
+
...(typeArguments > 0 ? { root_type_arguments: typeArguments } : {}),
|
|
1466
1638
|
};
|
|
1467
1639
|
}
|
|
1468
1640
|
inferVariable(sourceFile, request, extractionConfig) {
|
|
@@ -1834,9 +2006,9 @@ export class TypeInferrer {
|
|
|
1834
2006
|
continue;
|
|
1835
2007
|
}
|
|
1836
2008
|
// The body a caller reads OUT of a transport response IS the payload
|
|
1837
|
-
// of the call that produced it: `res.json()` on the
|
|
1838
|
-
// with whatever `as T` the source states around it
|
|
1839
|
-
// `extractExplicitTypeFromAncestor` below. A bare identifier never
|
|
2009
|
+
// of the call that produced it: `res.json()` or `res.text()` on the
|
|
2010
|
+
// tracked binding, with whatever `as T` the source states around it
|
|
2011
|
+
// read by `extractExplicitTypeFromAncestor` below. A bare identifier never
|
|
1840
2012
|
// matches `expressionUsesNames` (it tests DESCENDANTS), so without
|
|
1841
2013
|
// this the body read is invisible to the def-use walk.
|
|
1842
2014
|
if (Node.isIdentifier(expr) && this.isIdentifierUsage(expr, currentNames)) {
|
|
@@ -2094,10 +2266,10 @@ export class TypeInferrer {
|
|
|
2094
2266
|
* `query.data`, `envelope` in `envelope.list[0]` — or `undefined` when the
|
|
2095
2267
|
* identifier names the value itself.
|
|
2096
2268
|
*
|
|
2097
|
-
* A member CALL is not a projection: `res.
|
|
2269
|
+
* A member CALL is not a projection: `res.blob()` yields a body rather than
|
|
2098
2270
|
* a part of one, and what it returns stays the walk's business. The
|
|
2099
|
-
* zero-argument json body
|
|
2100
|
-
* is asked.
|
|
2271
|
+
* zero-argument json and text body reads have their own branch and are
|
|
2272
|
+
* taken before this is asked.
|
|
2101
2273
|
*/
|
|
2102
2274
|
projectionOnReceiver(identifier) {
|
|
2103
2275
|
const access = identifier.getParent();
|
|
@@ -2340,12 +2512,18 @@ export class TypeInferrer {
|
|
|
2340
2512
|
!this.leavesAPositionOpen(statedNode));
|
|
2341
2513
|
});
|
|
2342
2514
|
}
|
|
2515
|
+
/**
|
|
2516
|
+
* The zero-argument whole-body read that takes `identifier` as its receiver,
|
|
2517
|
+
* `res.json()` or `res.text()`, or `undefined`. A text read is a body read
|
|
2518
|
+
* like a json one (carrick#1842): without it, `return res.text()` left the
|
|
2519
|
+
* walk on the response binding and published the transport object.
|
|
2520
|
+
*/
|
|
2343
2521
|
bodyReadOnReceiver(identifier) {
|
|
2344
2522
|
const access = identifier.getParent();
|
|
2345
2523
|
if (!access ||
|
|
2346
2524
|
!Node.isPropertyAccessExpression(access) ||
|
|
2347
2525
|
access.getExpression() !== identifier ||
|
|
2348
|
-
access.getName()
|
|
2526
|
+
!WHOLE_BODY_READS.has(access.getName())) {
|
|
2349
2527
|
return undefined;
|
|
2350
2528
|
}
|
|
2351
2529
|
const call = access.getParent();
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
import { ts } from 'ts-morph';
|
|
32
32
|
import { canonicalizeUnionsInText, foldBooleanLiterals, } from './type-text-canonicalizer.js';
|
|
33
33
|
import { isExternalOrigin } from './origin.js';
|
|
34
|
+
import { notePrintedType } from './printed-names.js';
|
|
34
35
|
/**
|
|
35
36
|
* Bound on the structural-expansion recursion. Deep enough for every realistic
|
|
36
37
|
* request/response shape; a backstop against pathological/recursive types the
|
|
@@ -385,8 +386,16 @@ function isLibraryType(type, origin) {
|
|
|
385
386
|
export function namedText(type) {
|
|
386
387
|
return canonicalizeUnionsInText(compilerText(type));
|
|
387
388
|
}
|
|
388
|
-
/**
|
|
389
|
+
/**
|
|
390
|
+
* The compiler's print, with the two fallbacks. The print writes names bare,
|
|
391
|
+
* whatever scope reads it, so it is noted for the inference (carrick#1836).
|
|
392
|
+
*/
|
|
389
393
|
function compilerText(type) {
|
|
394
|
+
const text = compilerPrint(type);
|
|
395
|
+
notePrintedType(type, undefined, text);
|
|
396
|
+
return text;
|
|
397
|
+
}
|
|
398
|
+
function compilerPrint(type) {
|
|
390
399
|
try {
|
|
391
400
|
return type.getText(undefined, ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.InTypeAlias);
|
|
392
401
|
}
|
|
@@ -823,6 +823,23 @@ export interface InferredType {
|
|
|
823
823
|
* stated, or when the only annotation is further away than the read.
|
|
824
824
|
*/
|
|
825
825
|
stated_body?: StatedBody;
|
|
826
|
+
/**
|
|
827
|
+
* carrick#1836: the declarations behind the names `type_string` prints that
|
|
828
|
+
* the request's file does not resolve. The printer writes names bare where
|
|
829
|
+
* no scope reads them, so this is the only record of what they meant. A
|
|
830
|
+
* name printed for two declarations is listed twice. Absent when there is
|
|
831
|
+
* nothing to list.
|
|
832
|
+
*/
|
|
833
|
+
printed_names?: PrintedName[];
|
|
834
|
+
/**
|
|
835
|
+
* carrick#1842, `call_result` only: the published `string` is the body read
|
|
836
|
+
* as raw text, by a `.text()` read of the call's response or by a call whose
|
|
837
|
+
* signature takes the literal `'text'` the source passes as its body format.
|
|
838
|
+
* Raw text states no structural contract, so the check phase reads the pair
|
|
839
|
+
* unverifiable rather than comparing `string` with the other side's body.
|
|
840
|
+
* Absent when the body is not a raw-text read.
|
|
841
|
+
*/
|
|
842
|
+
raw_text_read?: true;
|
|
826
843
|
}
|
|
827
844
|
/**
|
|
828
845
|
* What the source states a body read to be (carrick#1749). The scanner
|
|
@@ -843,6 +860,11 @@ export interface StatedBody {
|
|
|
843
860
|
root_source?: string;
|
|
844
861
|
/** Array levels peeled on the way to `root`. Omitted when 0. */
|
|
845
862
|
array_depth?: number;
|
|
863
|
+
/**
|
|
864
|
+
* Type arguments written at `root` (`Page<Order>` → 1). Omitted when 0.
|
|
865
|
+
* `root` alone does not name the body such a statement states.
|
|
866
|
+
*/
|
|
867
|
+
root_type_arguments?: number;
|
|
846
868
|
}
|
|
847
869
|
/**
|
|
848
870
|
* Why a type carries `any`/`unknown` at a position, and where.
|
|
@@ -853,6 +875,8 @@ export interface StatedBody {
|
|
|
853
875
|
* across the bundle seam.
|
|
854
876
|
*/
|
|
855
877
|
export type TypeProvenance = import('./capture/api.js').TypeProvenance;
|
|
878
|
+
/** carrick#1836: declared in the capture bundle, which reads it on a literal anchor. */
|
|
879
|
+
export type PrintedName = import('./capture/api.js').PrintedName;
|
|
856
880
|
export type TypeProvenanceReason = import('./capture/api.js').TypeProvenanceReason;
|
|
857
881
|
/**
|
|
858
882
|
* Source location information for a type
|
|
@@ -332,18 +332,44 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
|
|
|
332
332
|
type_text: z.ZodString;
|
|
333
333
|
anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill", "manifest-placeholder"]>;
|
|
334
334
|
source_file: z.ZodOptional<z.ZodString>;
|
|
335
|
+
printed_names: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
336
|
+
name: z.ZodString;
|
|
337
|
+
file: z.ZodString;
|
|
338
|
+
export_path: z.ZodArray<z.ZodString, "many">;
|
|
339
|
+
}, "strip", z.ZodTypeAny, {
|
|
340
|
+
name: string;
|
|
341
|
+
file: string;
|
|
342
|
+
export_path: string[];
|
|
343
|
+
}, {
|
|
344
|
+
name: string;
|
|
345
|
+
file: string;
|
|
346
|
+
export_path: string[];
|
|
347
|
+
}>, "many">>;
|
|
348
|
+
raw_text_read: z.ZodOptional<z.ZodLiteral<true>>;
|
|
335
349
|
}, "strip", z.ZodTypeAny, {
|
|
336
350
|
kind: "literal";
|
|
337
351
|
alias: string;
|
|
338
352
|
anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
|
|
339
353
|
type_text: string;
|
|
340
354
|
source_file?: string | undefined;
|
|
355
|
+
printed_names?: {
|
|
356
|
+
name: string;
|
|
357
|
+
file: string;
|
|
358
|
+
export_path: string[];
|
|
359
|
+
}[] | undefined;
|
|
360
|
+
raw_text_read?: true | undefined;
|
|
341
361
|
}, {
|
|
342
362
|
kind: "literal";
|
|
343
363
|
alias: string;
|
|
344
364
|
anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
|
|
345
365
|
type_text: string;
|
|
346
366
|
source_file?: string | undefined;
|
|
367
|
+
printed_names?: {
|
|
368
|
+
name: string;
|
|
369
|
+
file: string;
|
|
370
|
+
export_path: string[];
|
|
371
|
+
}[] | undefined;
|
|
372
|
+
raw_text_read?: true | undefined;
|
|
347
373
|
}>]>, "many">;
|
|
348
374
|
out_dir: z.ZodString;
|
|
349
375
|
tsconfig_path: z.ZodOptional<z.ZodString>;
|
|
@@ -382,6 +408,12 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
|
|
|
382
408
|
anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
|
|
383
409
|
type_text: string;
|
|
384
410
|
source_file?: string | undefined;
|
|
411
|
+
printed_names?: {
|
|
412
|
+
name: string;
|
|
413
|
+
file: string;
|
|
414
|
+
export_path: string[];
|
|
415
|
+
}[] | undefined;
|
|
416
|
+
raw_text_read?: true | undefined;
|
|
385
417
|
})[];
|
|
386
418
|
out_dir: string;
|
|
387
419
|
tsconfig_path?: string | undefined;
|
|
@@ -420,6 +452,12 @@ export declare const CaptureV2RequestSchema: z.ZodObject<{
|
|
|
420
452
|
anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
|
|
421
453
|
type_text: string;
|
|
422
454
|
source_file?: string | undefined;
|
|
455
|
+
printed_names?: {
|
|
456
|
+
name: string;
|
|
457
|
+
file: string;
|
|
458
|
+
export_path: string[];
|
|
459
|
+
}[] | undefined;
|
|
460
|
+
raw_text_read?: true | undefined;
|
|
423
461
|
})[];
|
|
424
462
|
out_dir: string;
|
|
425
463
|
tsconfig_path?: string | undefined;
|
|
@@ -2077,18 +2115,44 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
|
|
|
2077
2115
|
type_text: z.ZodString;
|
|
2078
2116
|
anchor_origin: z.ZodEnum<["llm-symbol", "deterministic-infer", "anchor-backfill", "manifest-placeholder"]>;
|
|
2079
2117
|
source_file: z.ZodOptional<z.ZodString>;
|
|
2118
|
+
printed_names: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
2119
|
+
name: z.ZodString;
|
|
2120
|
+
file: z.ZodString;
|
|
2121
|
+
export_path: z.ZodArray<z.ZodString, "many">;
|
|
2122
|
+
}, "strip", z.ZodTypeAny, {
|
|
2123
|
+
name: string;
|
|
2124
|
+
file: string;
|
|
2125
|
+
export_path: string[];
|
|
2126
|
+
}, {
|
|
2127
|
+
name: string;
|
|
2128
|
+
file: string;
|
|
2129
|
+
export_path: string[];
|
|
2130
|
+
}>, "many">>;
|
|
2131
|
+
raw_text_read: z.ZodOptional<z.ZodLiteral<true>>;
|
|
2080
2132
|
}, "strip", z.ZodTypeAny, {
|
|
2081
2133
|
kind: "literal";
|
|
2082
2134
|
alias: string;
|
|
2083
2135
|
anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
|
|
2084
2136
|
type_text: string;
|
|
2085
2137
|
source_file?: string | undefined;
|
|
2138
|
+
printed_names?: {
|
|
2139
|
+
name: string;
|
|
2140
|
+
file: string;
|
|
2141
|
+
export_path: string[];
|
|
2142
|
+
}[] | undefined;
|
|
2143
|
+
raw_text_read?: true | undefined;
|
|
2086
2144
|
}, {
|
|
2087
2145
|
kind: "literal";
|
|
2088
2146
|
alias: string;
|
|
2089
2147
|
anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
|
|
2090
2148
|
type_text: string;
|
|
2091
2149
|
source_file?: string | undefined;
|
|
2150
|
+
printed_names?: {
|
|
2151
|
+
name: string;
|
|
2152
|
+
file: string;
|
|
2153
|
+
export_path: string[];
|
|
2154
|
+
}[] | undefined;
|
|
2155
|
+
raw_text_read?: true | undefined;
|
|
2092
2156
|
}>]>, "many">;
|
|
2093
2157
|
out_dir: z.ZodString;
|
|
2094
2158
|
tsconfig_path: z.ZodOptional<z.ZodString>;
|
|
@@ -2127,6 +2191,12 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
|
|
|
2127
2191
|
anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
|
|
2128
2192
|
type_text: string;
|
|
2129
2193
|
source_file?: string | undefined;
|
|
2194
|
+
printed_names?: {
|
|
2195
|
+
name: string;
|
|
2196
|
+
file: string;
|
|
2197
|
+
export_path: string[];
|
|
2198
|
+
}[] | undefined;
|
|
2199
|
+
raw_text_read?: true | undefined;
|
|
2130
2200
|
})[];
|
|
2131
2201
|
out_dir: string;
|
|
2132
2202
|
tsconfig_path?: string | undefined;
|
|
@@ -2165,6 +2235,12 @@ export declare const SidecarRequestSchema: z.ZodDiscriminatedUnion<"action", [z.
|
|
|
2165
2235
|
anchor_origin: "llm-symbol" | "deterministic-infer" | "anchor-backfill" | "manifest-placeholder";
|
|
2166
2236
|
type_text: string;
|
|
2167
2237
|
source_file?: string | undefined;
|
|
2238
|
+
printed_names?: {
|
|
2239
|
+
name: string;
|
|
2240
|
+
file: string;
|
|
2241
|
+
export_path: string[];
|
|
2242
|
+
}[] | undefined;
|
|
2243
|
+
raw_text_read?: true | undefined;
|
|
2168
2244
|
})[];
|
|
2169
2245
|
out_dir: string;
|
|
2170
2246
|
tsconfig_path?: string | undefined;
|
|
@@ -184,6 +184,14 @@ const CaptureAnchorRequestSchema = z.discriminatedUnion('kind', [
|
|
|
184
184
|
type_text: z.string().min(1),
|
|
185
185
|
anchor_origin: AnchorOriginSchema,
|
|
186
186
|
source_file: z.string().min(1).optional(),
|
|
187
|
+
printed_names: z
|
|
188
|
+
.array(z.object({
|
|
189
|
+
name: z.string().min(1),
|
|
190
|
+
file: z.string().min(1),
|
|
191
|
+
export_path: z.array(z.string().min(1)).min(1),
|
|
192
|
+
}))
|
|
193
|
+
.optional(),
|
|
194
|
+
raw_text_read: z.literal(true).optional(),
|
|
187
195
|
}),
|
|
188
196
|
]);
|
|
189
197
|
export const CaptureV2RequestSchema = BaseRequestSchema.extend({
|