@suss/adapter-python 0.22.4 → 0.24.0
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 +25 -417
- package/dist/index.cjs +4849 -4006
- package/dist/index.d.cts +207 -2
- package/dist/index.d.ts +207 -2
- package/dist/index.js +4881 -4039
- package/package.json +8 -8
package/dist/index.d.cts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { TypeShape, BehavioralSummary } from '@suss/behavioral-ir';
|
|
1
|
+
import { TypeShape, WrapperReference, BehavioralSummary } from '@suss/behavioral-ir';
|
|
2
2
|
import { Tree, Node } from 'web-tree-sitter';
|
|
3
3
|
export { Node as PyNode, Tree as PyTree } from 'web-tree-sitter';
|
|
4
4
|
import { Database } from '@suss/datalog';
|
|
5
|
-
import {
|
|
5
|
+
import { RawCodeStructure, ExtractorOptions, TimingReport, ExtractionReport, CacheDiagnostic } from '@suss/extractor';
|
|
6
6
|
import { WhyExplained } from '@suss/resolution';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -229,6 +229,8 @@ interface PythonPack {
|
|
|
229
229
|
* and never says why (#188).
|
|
230
230
|
*/
|
|
231
231
|
projectModules?: string[];
|
|
232
|
+
/** The callables the library gives a project for making a request. */
|
|
233
|
+
clients?: PyClientCall[];
|
|
232
234
|
/** What the library's own database queries look like. The README says how one is matched. */
|
|
233
235
|
storage?: StoragePattern[];
|
|
234
236
|
/** How the library lets a project hand the database SQL it wrote itself. */
|
|
@@ -285,6 +287,49 @@ interface RawSqlPattern {
|
|
|
285
287
|
storageSystem: "postgresql" | "mysql" | "sqlite";
|
|
286
288
|
}
|
|
287
289
|
type PythonDiscoveryPattern = DecoratedClassRoute | DecoratedFunctionRoute;
|
|
290
|
+
/**
|
|
291
|
+
* The callables a library gives a project for making a request. A
|
|
292
|
+
* function that calls one of them is a client of the boundary that call
|
|
293
|
+
* states, and gets a unit bound to its method and path.
|
|
294
|
+
*/
|
|
295
|
+
interface PyClientCall {
|
|
296
|
+
type: "clientCall";
|
|
297
|
+
/** The module the callables come from, `requests`. */
|
|
298
|
+
importModule: string[];
|
|
299
|
+
/** Attribute names that state the method themselves: `get` means GET. */
|
|
300
|
+
verbAttributeNames: Record<string, string>;
|
|
301
|
+
/** Where a call whose name states the method states its URL. */
|
|
302
|
+
url: {
|
|
303
|
+
position: number;
|
|
304
|
+
keyword: string;
|
|
305
|
+
};
|
|
306
|
+
/** A call that takes the method as an argument instead, `request("GET", url)`. */
|
|
307
|
+
methodCall?: {
|
|
308
|
+
attribute: string;
|
|
309
|
+
methodPosition: number;
|
|
310
|
+
methodKeyword?: string;
|
|
311
|
+
urlPosition: number;
|
|
312
|
+
};
|
|
313
|
+
/** Constructors whose instances take the same calls, `Session`. */
|
|
314
|
+
receiverConstructors?: string[];
|
|
315
|
+
/** What the response object gives a caller, so a guard on it reads as a guard on a status. */
|
|
316
|
+
response?: PyClientResponse;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* The members a library's response object gives a caller. A caller that
|
|
320
|
+
* tests one of them is saying which statuses it handles, and the
|
|
321
|
+
* checker compares that against what the other side produces.
|
|
322
|
+
*/
|
|
323
|
+
interface PyClientResponse {
|
|
324
|
+
/** Members whose value is the status code: `status_code`. */
|
|
325
|
+
statusCode?: string[];
|
|
326
|
+
/** Members that say the request succeeded, meaning a status in 200 to 299: `ok`. */
|
|
327
|
+
success?: string[];
|
|
328
|
+
/** Members that give the body: `json`, `text`, `content`. */
|
|
329
|
+
body?: string[];
|
|
330
|
+
/** Whether a refused request comes back as a response or raises where it was made. */
|
|
331
|
+
failureDelivery?: "response" | "exception";
|
|
332
|
+
}
|
|
288
333
|
/** Conventions both kinds of route share. Each one describes what the library does, never a project's choice. */
|
|
289
334
|
interface RouteConventions {
|
|
290
335
|
/** How the library spells a path parameter. The README lists the syntaxes we know how to read. */
|
|
@@ -323,8 +368,74 @@ interface RouteConventions {
|
|
|
323
368
|
* and one it does cover comes out as the response the library sends.
|
|
324
369
|
*/
|
|
325
370
|
responseStatusCalls?: PyStatusCall[];
|
|
371
|
+
/**
|
|
372
|
+
* The library's own classes whose instance, when a body returns it, is
|
|
373
|
+
* the response the library sends, and where each takes the status:
|
|
374
|
+
* Starlette's `JSONResponse(status_code=...)`. A return of one says its
|
|
375
|
+
* own status; a return of anything else keeps the declared one.
|
|
376
|
+
*/
|
|
377
|
+
responseConstructors?: PyStatusCall[];
|
|
326
378
|
/** Unset means the library has no router mounting, and a route's decorator path stands as written. */
|
|
327
379
|
routerComposition?: RouterComposition;
|
|
380
|
+
/** The ways the library runs a project's own function around a route. The README lists what each one covers. */
|
|
381
|
+
wrappers?: PyWrapperForm[];
|
|
382
|
+
}
|
|
383
|
+
type PyWrapperForm = PyDependencyForm | PyDecoratedWrapperForm;
|
|
384
|
+
/** Where a wrapper is registered, and which routes the registration reaches. */
|
|
385
|
+
interface PyWrapperRegistrar {
|
|
386
|
+
/** The constructor of the object the registration is written on, as the library exports it: `FastAPI`, `APIRouter`. */
|
|
387
|
+
constructorName: string;
|
|
388
|
+
/** Where the constructor is imported from, when that is not the pattern's own `importModule`: `flask` for the app a flask-restx API is served by. */
|
|
389
|
+
importModule?: string[];
|
|
390
|
+
/**
|
|
391
|
+
* `everyRoute` for the app, whose registration reaches every route of
|
|
392
|
+
* the pack in the run. `ownRoutes` for a router or a blueprint, whose
|
|
393
|
+
* registration reaches the routes decorated on that same object.
|
|
394
|
+
*/
|
|
395
|
+
covers: "everyRoute" | "ownRoutes";
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* The library calls a project function before the handler, given as an
|
|
399
|
+
* argument to one of its own callables: FastAPI's `Depends(get_user)`.
|
|
400
|
+
* One may be written as a parameter default or inside `Annotated[...]`
|
|
401
|
+
* on the route, or in a list under `keyword` on the route decorator or
|
|
402
|
+
* on one of the registrars. The function runs before the handler and
|
|
403
|
+
* ends the request by raising, so it is a wrapper whose every return
|
|
404
|
+
* hands on.
|
|
405
|
+
*/
|
|
406
|
+
interface PyDependencyForm {
|
|
407
|
+
type: "dependency";
|
|
408
|
+
/** The callables that take the function: `Depends`, `Security`. */
|
|
409
|
+
callees: string[];
|
|
410
|
+
/** The keyword a list of them is written under: `dependencies`. */
|
|
411
|
+
keyword: string;
|
|
412
|
+
registrars: PyWrapperRegistrar[];
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* A project function decorated with a method on the app or a router:
|
|
416
|
+
* `@app.middleware("http")`, `@app.exception_handler(ValueError)`,
|
|
417
|
+
* `@app.before_request`. What the decorated function's returns mean
|
|
418
|
+
* depends on which of the three fields below is set; with none set,
|
|
419
|
+
* every return hands the request on.
|
|
420
|
+
*/
|
|
421
|
+
interface PyDecoratedWrapperForm {
|
|
422
|
+
type: "decoratedWrapper";
|
|
423
|
+
/** The decorator's attribute name on the registrar: `middleware`. */
|
|
424
|
+
attribute: string;
|
|
425
|
+
registrars: PyWrapperRegistrar[];
|
|
426
|
+
/**
|
|
427
|
+
* The position of the parameter the wrapper calls to run what it
|
|
428
|
+
* wraps, `call_next` at 1 for Starlette middleware. A return before
|
|
429
|
+
* that call ends the request with what is returned.
|
|
430
|
+
*/
|
|
431
|
+
continuationParam?: number;
|
|
432
|
+
/**
|
|
433
|
+
* Set when a value returned ends the request and only a bare return
|
|
434
|
+
* hands on, which is what Flask does with `before_request`.
|
|
435
|
+
*/
|
|
436
|
+
returnedValueResponds?: boolean;
|
|
437
|
+
/** The position the library hands the raised exception at. Set on an error handler, which runs only when the handler raised. */
|
|
438
|
+
throwParam?: number;
|
|
328
439
|
}
|
|
329
440
|
/**
|
|
330
441
|
* One callable that ends the request, and where it takes the status.
|
|
@@ -577,6 +688,98 @@ interface RouterIndexOptions extends ModuleResolverOptions {
|
|
|
577
688
|
}
|
|
578
689
|
declare function buildRouterIndex(files: BoundPythonFile[], packs: PythonPack[], resolverOptions: RouterIndexOptions): RouterIndex;
|
|
579
690
|
|
|
691
|
+
/**
|
|
692
|
+
* What a call's callee is, read through the binder and the import
|
|
693
|
+
* facts: a function in this run the walk can step into, or a reason it
|
|
694
|
+
* cannot. A name is followed only through a binding that says where it
|
|
695
|
+
* came from, so a name that could be two definitions is a stop rather
|
|
696
|
+
* than a guess. The package README lists the spellings that are
|
|
697
|
+
* followed and the ones that stop.
|
|
698
|
+
*/
|
|
699
|
+
|
|
700
|
+
/** A function in this run, and the export path its summary gets. */
|
|
701
|
+
interface ReachedFunction {
|
|
702
|
+
readonly file: BoundPythonFile;
|
|
703
|
+
/** The `function_definition` node. */
|
|
704
|
+
readonly node: Node;
|
|
705
|
+
readonly name: string;
|
|
706
|
+
/** `[name]` for a module function, `[Class, name]` for a method. */
|
|
707
|
+
readonly exportPath: string[];
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* The project functions a library runs around a route, read from where
|
|
712
|
+
* they are registered: a dependency on a route's parameter or decorator,
|
|
713
|
+
* a dependency list on the app or a router, a function decorated with
|
|
714
|
+
* `@app.middleware(...)` or `@app.exception_handler(...)`. Each one
|
|
715
|
+
* becomes a unit of its own, and every route it reaches lists it, so the
|
|
716
|
+
* extractor can fold its outcomes into the route's. The README says which
|
|
717
|
+
* registrations are read and which are not.
|
|
718
|
+
*
|
|
719
|
+
* A registration on the app reaches every route of the pack in the run,
|
|
720
|
+
* since an app is one per run for every pack that has one. A registration
|
|
721
|
+
* on a router reaches the routes decorated on that same router object,
|
|
722
|
+
* and nothing mounted onto it.
|
|
723
|
+
*/
|
|
724
|
+
|
|
725
|
+
interface WrapperIndexOptions {
|
|
726
|
+
packs: readonly PythonPack[];
|
|
727
|
+
roots: string[];
|
|
728
|
+
facts: Database | undefined;
|
|
729
|
+
storageFor: (file: BoundPythonFile) => StorageLookup | undefined;
|
|
730
|
+
}
|
|
731
|
+
/** The route asking which wrappers reach it: the decorator it was found by, and where that decorator was read. */
|
|
732
|
+
interface RouteWrapperQuery {
|
|
733
|
+
pack: PythonPack;
|
|
734
|
+
pattern: PythonDiscoveryPattern;
|
|
735
|
+
/** The absolute path of the file the route is written in. */
|
|
736
|
+
file: string;
|
|
737
|
+
module: ModuleBinding;
|
|
738
|
+
classification: DecoratorClassification;
|
|
739
|
+
definitionNode: Node;
|
|
740
|
+
}
|
|
741
|
+
/** A wrapper the index has a unit for, and the form it was registered through. */
|
|
742
|
+
interface Registered {
|
|
743
|
+
reference: WrapperReference;
|
|
744
|
+
form: PyWrapperForm;
|
|
745
|
+
}
|
|
746
|
+
interface FormOf {
|
|
747
|
+
pack: PythonPack;
|
|
748
|
+
pattern: PythonDiscoveryPattern;
|
|
749
|
+
form: PyWrapperForm;
|
|
750
|
+
}
|
|
751
|
+
/** What every registration in the run reaches, asked once per route and then once per file for the wrapper units. */
|
|
752
|
+
declare class PythonWrapperIndex {
|
|
753
|
+
readonly options: WrapperIndexOptions;
|
|
754
|
+
readonly filesByPath: ReadonlyMap<string, BoundPythonFile>;
|
|
755
|
+
/** By pack name: what the app registered, in the order the forms are declared and then the order the files were read. */
|
|
756
|
+
private readonly everyRoute;
|
|
757
|
+
/** By construction key: what a router or a blueprint registered. */
|
|
758
|
+
private readonly ownRoutes;
|
|
759
|
+
private readonly unitsByKey;
|
|
760
|
+
private readonly unitsByFile;
|
|
761
|
+
constructor(options: WrapperIndexOptions, filesByPath: ReadonlyMap<string, BoundPythonFile>);
|
|
762
|
+
register(covers: {
|
|
763
|
+
kind: "everyRoute";
|
|
764
|
+
pack: string;
|
|
765
|
+
} | {
|
|
766
|
+
kind: "ownRoutes";
|
|
767
|
+
key: string;
|
|
768
|
+
}, target: ReachedFunction, declared: FormOf): void;
|
|
769
|
+
/** The unit for a function, built once however many registrations point at it. */
|
|
770
|
+
registered(target: ReachedFunction, declared: FormOf): Registered;
|
|
771
|
+
wrappersFor(query: RouteWrapperQuery): WrapperReference[];
|
|
772
|
+
private ownRoutesOf;
|
|
773
|
+
/**
|
|
774
|
+
* Where the decorator's object was built: the route's own file, the file
|
|
775
|
+
* a project wrapper function is written in, or the file an imported
|
|
776
|
+
* router comes from. The name is the one that file binds it under.
|
|
777
|
+
*/
|
|
778
|
+
private objectSiteOf;
|
|
779
|
+
private fileOfModule;
|
|
780
|
+
unitsIn(file: string): RawCodeStructure[];
|
|
781
|
+
}
|
|
782
|
+
|
|
580
783
|
/**
|
|
581
784
|
* Finds decorated routes and turns each one into a `RawCodeStructure`.
|
|
582
785
|
*
|
|
@@ -605,6 +808,8 @@ interface DiscoveryOptions {
|
|
|
605
808
|
absoluteFile?: string | undefined;
|
|
606
809
|
/** The project's facts, so the rules can say what an object no scope has a binding for was built by. */
|
|
607
810
|
facts?: Database | undefined;
|
|
811
|
+
/** What the project registered around its routes. Absent when no pack declares a wrapper form, or when a caller reads one file on its own. */
|
|
812
|
+
wrappers?: PythonWrapperIndex | undefined;
|
|
608
813
|
}
|
|
609
814
|
declare function discoverUnits(root: Node, module: ModuleBinding, options: DiscoveryOptions): RawCodeStructure[];
|
|
610
815
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { TypeShape, BehavioralSummary } from '@suss/behavioral-ir';
|
|
1
|
+
import { TypeShape, WrapperReference, BehavioralSummary } from '@suss/behavioral-ir';
|
|
2
2
|
import { Tree, Node } from 'web-tree-sitter';
|
|
3
3
|
export { Node as PyNode, Tree as PyTree } from 'web-tree-sitter';
|
|
4
4
|
import { Database } from '@suss/datalog';
|
|
5
|
-
import {
|
|
5
|
+
import { RawCodeStructure, ExtractorOptions, TimingReport, ExtractionReport, CacheDiagnostic } from '@suss/extractor';
|
|
6
6
|
import { WhyExplained } from '@suss/resolution';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -229,6 +229,8 @@ interface PythonPack {
|
|
|
229
229
|
* and never says why (#188).
|
|
230
230
|
*/
|
|
231
231
|
projectModules?: string[];
|
|
232
|
+
/** The callables the library gives a project for making a request. */
|
|
233
|
+
clients?: PyClientCall[];
|
|
232
234
|
/** What the library's own database queries look like. The README says how one is matched. */
|
|
233
235
|
storage?: StoragePattern[];
|
|
234
236
|
/** How the library lets a project hand the database SQL it wrote itself. */
|
|
@@ -285,6 +287,49 @@ interface RawSqlPattern {
|
|
|
285
287
|
storageSystem: "postgresql" | "mysql" | "sqlite";
|
|
286
288
|
}
|
|
287
289
|
type PythonDiscoveryPattern = DecoratedClassRoute | DecoratedFunctionRoute;
|
|
290
|
+
/**
|
|
291
|
+
* The callables a library gives a project for making a request. A
|
|
292
|
+
* function that calls one of them is a client of the boundary that call
|
|
293
|
+
* states, and gets a unit bound to its method and path.
|
|
294
|
+
*/
|
|
295
|
+
interface PyClientCall {
|
|
296
|
+
type: "clientCall";
|
|
297
|
+
/** The module the callables come from, `requests`. */
|
|
298
|
+
importModule: string[];
|
|
299
|
+
/** Attribute names that state the method themselves: `get` means GET. */
|
|
300
|
+
verbAttributeNames: Record<string, string>;
|
|
301
|
+
/** Where a call whose name states the method states its URL. */
|
|
302
|
+
url: {
|
|
303
|
+
position: number;
|
|
304
|
+
keyword: string;
|
|
305
|
+
};
|
|
306
|
+
/** A call that takes the method as an argument instead, `request("GET", url)`. */
|
|
307
|
+
methodCall?: {
|
|
308
|
+
attribute: string;
|
|
309
|
+
methodPosition: number;
|
|
310
|
+
methodKeyword?: string;
|
|
311
|
+
urlPosition: number;
|
|
312
|
+
};
|
|
313
|
+
/** Constructors whose instances take the same calls, `Session`. */
|
|
314
|
+
receiverConstructors?: string[];
|
|
315
|
+
/** What the response object gives a caller, so a guard on it reads as a guard on a status. */
|
|
316
|
+
response?: PyClientResponse;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* The members a library's response object gives a caller. A caller that
|
|
320
|
+
* tests one of them is saying which statuses it handles, and the
|
|
321
|
+
* checker compares that against what the other side produces.
|
|
322
|
+
*/
|
|
323
|
+
interface PyClientResponse {
|
|
324
|
+
/** Members whose value is the status code: `status_code`. */
|
|
325
|
+
statusCode?: string[];
|
|
326
|
+
/** Members that say the request succeeded, meaning a status in 200 to 299: `ok`. */
|
|
327
|
+
success?: string[];
|
|
328
|
+
/** Members that give the body: `json`, `text`, `content`. */
|
|
329
|
+
body?: string[];
|
|
330
|
+
/** Whether a refused request comes back as a response or raises where it was made. */
|
|
331
|
+
failureDelivery?: "response" | "exception";
|
|
332
|
+
}
|
|
288
333
|
/** Conventions both kinds of route share. Each one describes what the library does, never a project's choice. */
|
|
289
334
|
interface RouteConventions {
|
|
290
335
|
/** How the library spells a path parameter. The README lists the syntaxes we know how to read. */
|
|
@@ -323,8 +368,74 @@ interface RouteConventions {
|
|
|
323
368
|
* and one it does cover comes out as the response the library sends.
|
|
324
369
|
*/
|
|
325
370
|
responseStatusCalls?: PyStatusCall[];
|
|
371
|
+
/**
|
|
372
|
+
* The library's own classes whose instance, when a body returns it, is
|
|
373
|
+
* the response the library sends, and where each takes the status:
|
|
374
|
+
* Starlette's `JSONResponse(status_code=...)`. A return of one says its
|
|
375
|
+
* own status; a return of anything else keeps the declared one.
|
|
376
|
+
*/
|
|
377
|
+
responseConstructors?: PyStatusCall[];
|
|
326
378
|
/** Unset means the library has no router mounting, and a route's decorator path stands as written. */
|
|
327
379
|
routerComposition?: RouterComposition;
|
|
380
|
+
/** The ways the library runs a project's own function around a route. The README lists what each one covers. */
|
|
381
|
+
wrappers?: PyWrapperForm[];
|
|
382
|
+
}
|
|
383
|
+
type PyWrapperForm = PyDependencyForm | PyDecoratedWrapperForm;
|
|
384
|
+
/** Where a wrapper is registered, and which routes the registration reaches. */
|
|
385
|
+
interface PyWrapperRegistrar {
|
|
386
|
+
/** The constructor of the object the registration is written on, as the library exports it: `FastAPI`, `APIRouter`. */
|
|
387
|
+
constructorName: string;
|
|
388
|
+
/** Where the constructor is imported from, when that is not the pattern's own `importModule`: `flask` for the app a flask-restx API is served by. */
|
|
389
|
+
importModule?: string[];
|
|
390
|
+
/**
|
|
391
|
+
* `everyRoute` for the app, whose registration reaches every route of
|
|
392
|
+
* the pack in the run. `ownRoutes` for a router or a blueprint, whose
|
|
393
|
+
* registration reaches the routes decorated on that same object.
|
|
394
|
+
*/
|
|
395
|
+
covers: "everyRoute" | "ownRoutes";
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* The library calls a project function before the handler, given as an
|
|
399
|
+
* argument to one of its own callables: FastAPI's `Depends(get_user)`.
|
|
400
|
+
* One may be written as a parameter default or inside `Annotated[...]`
|
|
401
|
+
* on the route, or in a list under `keyword` on the route decorator or
|
|
402
|
+
* on one of the registrars. The function runs before the handler and
|
|
403
|
+
* ends the request by raising, so it is a wrapper whose every return
|
|
404
|
+
* hands on.
|
|
405
|
+
*/
|
|
406
|
+
interface PyDependencyForm {
|
|
407
|
+
type: "dependency";
|
|
408
|
+
/** The callables that take the function: `Depends`, `Security`. */
|
|
409
|
+
callees: string[];
|
|
410
|
+
/** The keyword a list of them is written under: `dependencies`. */
|
|
411
|
+
keyword: string;
|
|
412
|
+
registrars: PyWrapperRegistrar[];
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* A project function decorated with a method on the app or a router:
|
|
416
|
+
* `@app.middleware("http")`, `@app.exception_handler(ValueError)`,
|
|
417
|
+
* `@app.before_request`. What the decorated function's returns mean
|
|
418
|
+
* depends on which of the three fields below is set; with none set,
|
|
419
|
+
* every return hands the request on.
|
|
420
|
+
*/
|
|
421
|
+
interface PyDecoratedWrapperForm {
|
|
422
|
+
type: "decoratedWrapper";
|
|
423
|
+
/** The decorator's attribute name on the registrar: `middleware`. */
|
|
424
|
+
attribute: string;
|
|
425
|
+
registrars: PyWrapperRegistrar[];
|
|
426
|
+
/**
|
|
427
|
+
* The position of the parameter the wrapper calls to run what it
|
|
428
|
+
* wraps, `call_next` at 1 for Starlette middleware. A return before
|
|
429
|
+
* that call ends the request with what is returned.
|
|
430
|
+
*/
|
|
431
|
+
continuationParam?: number;
|
|
432
|
+
/**
|
|
433
|
+
* Set when a value returned ends the request and only a bare return
|
|
434
|
+
* hands on, which is what Flask does with `before_request`.
|
|
435
|
+
*/
|
|
436
|
+
returnedValueResponds?: boolean;
|
|
437
|
+
/** The position the library hands the raised exception at. Set on an error handler, which runs only when the handler raised. */
|
|
438
|
+
throwParam?: number;
|
|
328
439
|
}
|
|
329
440
|
/**
|
|
330
441
|
* One callable that ends the request, and where it takes the status.
|
|
@@ -577,6 +688,98 @@ interface RouterIndexOptions extends ModuleResolverOptions {
|
|
|
577
688
|
}
|
|
578
689
|
declare function buildRouterIndex(files: BoundPythonFile[], packs: PythonPack[], resolverOptions: RouterIndexOptions): RouterIndex;
|
|
579
690
|
|
|
691
|
+
/**
|
|
692
|
+
* What a call's callee is, read through the binder and the import
|
|
693
|
+
* facts: a function in this run the walk can step into, or a reason it
|
|
694
|
+
* cannot. A name is followed only through a binding that says where it
|
|
695
|
+
* came from, so a name that could be two definitions is a stop rather
|
|
696
|
+
* than a guess. The package README lists the spellings that are
|
|
697
|
+
* followed and the ones that stop.
|
|
698
|
+
*/
|
|
699
|
+
|
|
700
|
+
/** A function in this run, and the export path its summary gets. */
|
|
701
|
+
interface ReachedFunction {
|
|
702
|
+
readonly file: BoundPythonFile;
|
|
703
|
+
/** The `function_definition` node. */
|
|
704
|
+
readonly node: Node;
|
|
705
|
+
readonly name: string;
|
|
706
|
+
/** `[name]` for a module function, `[Class, name]` for a method. */
|
|
707
|
+
readonly exportPath: string[];
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* The project functions a library runs around a route, read from where
|
|
712
|
+
* they are registered: a dependency on a route's parameter or decorator,
|
|
713
|
+
* a dependency list on the app or a router, a function decorated with
|
|
714
|
+
* `@app.middleware(...)` or `@app.exception_handler(...)`. Each one
|
|
715
|
+
* becomes a unit of its own, and every route it reaches lists it, so the
|
|
716
|
+
* extractor can fold its outcomes into the route's. The README says which
|
|
717
|
+
* registrations are read and which are not.
|
|
718
|
+
*
|
|
719
|
+
* A registration on the app reaches every route of the pack in the run,
|
|
720
|
+
* since an app is one per run for every pack that has one. A registration
|
|
721
|
+
* on a router reaches the routes decorated on that same router object,
|
|
722
|
+
* and nothing mounted onto it.
|
|
723
|
+
*/
|
|
724
|
+
|
|
725
|
+
interface WrapperIndexOptions {
|
|
726
|
+
packs: readonly PythonPack[];
|
|
727
|
+
roots: string[];
|
|
728
|
+
facts: Database | undefined;
|
|
729
|
+
storageFor: (file: BoundPythonFile) => StorageLookup | undefined;
|
|
730
|
+
}
|
|
731
|
+
/** The route asking which wrappers reach it: the decorator it was found by, and where that decorator was read. */
|
|
732
|
+
interface RouteWrapperQuery {
|
|
733
|
+
pack: PythonPack;
|
|
734
|
+
pattern: PythonDiscoveryPattern;
|
|
735
|
+
/** The absolute path of the file the route is written in. */
|
|
736
|
+
file: string;
|
|
737
|
+
module: ModuleBinding;
|
|
738
|
+
classification: DecoratorClassification;
|
|
739
|
+
definitionNode: Node;
|
|
740
|
+
}
|
|
741
|
+
/** A wrapper the index has a unit for, and the form it was registered through. */
|
|
742
|
+
interface Registered {
|
|
743
|
+
reference: WrapperReference;
|
|
744
|
+
form: PyWrapperForm;
|
|
745
|
+
}
|
|
746
|
+
interface FormOf {
|
|
747
|
+
pack: PythonPack;
|
|
748
|
+
pattern: PythonDiscoveryPattern;
|
|
749
|
+
form: PyWrapperForm;
|
|
750
|
+
}
|
|
751
|
+
/** What every registration in the run reaches, asked once per route and then once per file for the wrapper units. */
|
|
752
|
+
declare class PythonWrapperIndex {
|
|
753
|
+
readonly options: WrapperIndexOptions;
|
|
754
|
+
readonly filesByPath: ReadonlyMap<string, BoundPythonFile>;
|
|
755
|
+
/** By pack name: what the app registered, in the order the forms are declared and then the order the files were read. */
|
|
756
|
+
private readonly everyRoute;
|
|
757
|
+
/** By construction key: what a router or a blueprint registered. */
|
|
758
|
+
private readonly ownRoutes;
|
|
759
|
+
private readonly unitsByKey;
|
|
760
|
+
private readonly unitsByFile;
|
|
761
|
+
constructor(options: WrapperIndexOptions, filesByPath: ReadonlyMap<string, BoundPythonFile>);
|
|
762
|
+
register(covers: {
|
|
763
|
+
kind: "everyRoute";
|
|
764
|
+
pack: string;
|
|
765
|
+
} | {
|
|
766
|
+
kind: "ownRoutes";
|
|
767
|
+
key: string;
|
|
768
|
+
}, target: ReachedFunction, declared: FormOf): void;
|
|
769
|
+
/** The unit for a function, built once however many registrations point at it. */
|
|
770
|
+
registered(target: ReachedFunction, declared: FormOf): Registered;
|
|
771
|
+
wrappersFor(query: RouteWrapperQuery): WrapperReference[];
|
|
772
|
+
private ownRoutesOf;
|
|
773
|
+
/**
|
|
774
|
+
* Where the decorator's object was built: the route's own file, the file
|
|
775
|
+
* a project wrapper function is written in, or the file an imported
|
|
776
|
+
* router comes from. The name is the one that file binds it under.
|
|
777
|
+
*/
|
|
778
|
+
private objectSiteOf;
|
|
779
|
+
private fileOfModule;
|
|
780
|
+
unitsIn(file: string): RawCodeStructure[];
|
|
781
|
+
}
|
|
782
|
+
|
|
580
783
|
/**
|
|
581
784
|
* Finds decorated routes and turns each one into a `RawCodeStructure`.
|
|
582
785
|
*
|
|
@@ -605,6 +808,8 @@ interface DiscoveryOptions {
|
|
|
605
808
|
absoluteFile?: string | undefined;
|
|
606
809
|
/** The project's facts, so the rules can say what an object no scope has a binding for was built by. */
|
|
607
810
|
facts?: Database | undefined;
|
|
811
|
+
/** What the project registered around its routes. Absent when no pack declares a wrapper form, or when a caller reads one file on its own. */
|
|
812
|
+
wrappers?: PythonWrapperIndex | undefined;
|
|
608
813
|
}
|
|
609
814
|
declare function discoverUnits(root: Node, module: ModuleBinding, options: DiscoveryOptions): RawCodeStructure[];
|
|
610
815
|
|