@descryy/adapter-python 0.1.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/dist/adapter.d.ts +75 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +481 -0
- package/dist/adapter.js.map +1 -0
- package/dist/client.d.ts +117 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +347 -0
- package/dist/client.js.map +1 -0
- package/dist/extract.d.ts +231 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +2267 -0
- package/dist/extract.js.map +1 -0
- package/dist/extract.py +1319 -0
- package/dist/graphql.d.ts +197 -0
- package/dist/graphql.d.ts.map +1 -0
- package/dist/graphql.js +302 -0
- package/dist/graphql.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/module.d.ts +99 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +211 -0
- package/dist/module.js.map +1 -0
- package/dist/orm.d.ts +102 -0
- package/dist/orm.d.ts.map +1 -0
- package/dist/orm.js +221 -0
- package/dist/orm.js.map +1 -0
- package/dist/pydantic.d.ts +157 -0
- package/dist/pydantic.d.ts.map +1 -0
- package/dist/pydantic.js +318 -0
- package/dist/pydantic.js.map +1 -0
- package/dist/pytest-config.d.ts +60 -0
- package/dist/pytest-config.d.ts.map +1 -0
- package/dist/pytest-config.js +147 -0
- package/dist/pytest-config.js.map +1 -0
- package/dist/routes.d.ts +249 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +511 -0
- package/dist/routes.js.map +1 -0
- package/package.json +34 -0
- package/src/extract.py +1319 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The GraphQL root-operation extractor for Python — strawberry and
|
|
3
|
+
* strawberry-django.
|
|
4
|
+
*
|
|
5
|
+
* ## The identity, and where it comes from
|
|
6
|
+
*
|
|
7
|
+
* `API_ROUTE`/`API_ENDPOINT` identity is `METHOD /path`, and a GraphQL field has
|
|
8
|
+
* neither a verb nor a URL. `DEC-NEXT-graphql-operation-identity` (descry-core)
|
|
9
|
+
* settles it by transposing the gRPC precedent
|
|
10
|
+
* (`DEC-NEXT-grpc-route-identity`), because deciding it here in isolation is how
|
|
11
|
+
* two producers of one operation end up with two conventions and no join:
|
|
12
|
+
*
|
|
13
|
+
* - **`method` is the literal sentinel `"GRAPHQL"`** — one per protocol, the
|
|
14
|
+
* way gRPC has exactly one `"RPC"` rather than a sentinel per RPC kind. It is
|
|
15
|
+
* not load-bearing for identity (the path alone is unique); it exists so a
|
|
16
|
+
* human or a UI reading `attrs.method` knows not to expect `GET`.
|
|
17
|
+
* - **The path is `/<OperationType>/<field>`** — `/Query/circuit`,
|
|
18
|
+
* `/Mutation/create_order`, `/Subscription/message_added`. GraphQL's root
|
|
19
|
+
* operation type is the structural analogue of gRPC's Service and the field
|
|
20
|
+
* name the analogue of its Method.
|
|
21
|
+
*
|
|
22
|
+
* ## The departure from the precedent, and how it is narrowed
|
|
23
|
+
*
|
|
24
|
+
* gRPC's decision leans on **"the path is read, not assembled"**: protoc writes
|
|
25
|
+
* `Service_Method_FullMethodName = "/pkg.Service/Method"` and the reader takes
|
|
26
|
+
* that literal verbatim. **strawberry writes no such artifact.** The schema is
|
|
27
|
+
* built at import time from the class structure, and the schema-facing field
|
|
28
|
+
* name is not always the Python name:
|
|
29
|
+
*
|
|
30
|
+
* | strawberry's own rule | consequence here |
|
|
31
|
+
* | --- | --- |
|
|
32
|
+
* | `NameConverter.auto_camel_case` defaults to **True** | `circuit_list` is served as `circuitList` |
|
|
33
|
+
* | an explicit `graphql_name` returns before `apply_naming_config` | `field(name="allCircuits")` is the name, verbatim |
|
|
34
|
+
* | `to_camel_case` is `s.split("_")`, rejoined | a name with **no** `_` is unchanged by it |
|
|
35
|
+
*
|
|
36
|
+
* So this reader admits a field **only when its schema-facing name can be read
|
|
37
|
+
* verbatim out of the source** — the three rows above give exactly three such
|
|
38
|
+
* cases, and `readFieldName` is the whole rule. Anything else is refused and
|
|
39
|
+
* disclosed. **The reader never computes a name.** Writing `circuitList` — a
|
|
40
|
+
* string that appears nowhere in the repository — because a library default
|
|
41
|
+
* says it should is precisely the DEC-055 shape both decisions exist to
|
|
42
|
+
* prevent: everything normalises, everything resolves, and the join is silently
|
|
43
|
+
* zero because the consumer half read the real wire name and this half invented
|
|
44
|
+
* a plausible one.
|
|
45
|
+
*
|
|
46
|
+
* The half that *is* still assembled is the `/Query/` prefix, and it is
|
|
47
|
+
* assembled out of the schema call's own slot keyword (`query=`/`mutation=`/
|
|
48
|
+
* `subscription=`) rather than out of any Python name. The three operation-type
|
|
49
|
+
* words are GraphQL's, fixed by the specification, and a client addresses an
|
|
50
|
+
* operation by its slot — never by the root class's name. That is why a class
|
|
51
|
+
* decorated `@strawberry.type(name="Query")` sitting in the `mutation=` slot
|
|
52
|
+
* yields `/Mutation/...` here, and why netbox's ten mixins all decorated
|
|
53
|
+
* `name="Query"` are read through the slot their root occupies rather than
|
|
54
|
+
* through a decorator that strawberry itself discards for a base class.
|
|
55
|
+
*
|
|
56
|
+
* ## The provenance rule, which does the precision work
|
|
57
|
+
*
|
|
58
|
+
* A field becomes an operation only when **a `strawberry.Schema(...)` call,
|
|
59
|
+
* whose callee resolves through the import table to strawberry's own module,
|
|
60
|
+
* puts its class in a root slot.** Not because a class is decorated
|
|
61
|
+
* `@strawberry.type` — netbox has 34 of those and 10 are root mixins — and
|
|
62
|
+
* never because an attribute is spelled like a field. This is `routes.ts`'s
|
|
63
|
+
* "the receiver must resolve to a router constructed from a web framework's own
|
|
64
|
+
* module" rule in a second spelling, and it is the same lesson: a node type
|
|
65
|
+
* comes from provenance or from nothing.
|
|
66
|
+
*
|
|
67
|
+
* The split with `extract.py` is this adapter's standing one — the Python side
|
|
68
|
+
* records syntactic form and names no framework, every decision about what a
|
|
69
|
+
* form *means* is taken here.
|
|
70
|
+
*/
|
|
71
|
+
import type { PyCall } from "./extract.ts";
|
|
72
|
+
import type { PyAttribute } from "./orm.ts";
|
|
73
|
+
/**
|
|
74
|
+
* The protocol sentinel. One per protocol, per `DEC-NEXT-grpc-route-identity`'s
|
|
75
|
+
* `"RPC"` — deliberately not split into QUERY/MUTATION/SUBSCRIPTION, because
|
|
76
|
+
* the operation type is carried in the path where gRPC carries the service.
|
|
77
|
+
*/
|
|
78
|
+
export declare const GRAPHQL_METHOD = "GRAPHQL";
|
|
79
|
+
/** GraphQL's three root operation types, fixed by the specification. */
|
|
80
|
+
export declare const OPERATION_SLOTS: readonly ["query", "mutation", "subscription"];
|
|
81
|
+
export type OperationSlot = (typeof OPERATION_SLOTS)[number];
|
|
82
|
+
/** The path segment each slot contributes — the specification's own spelling. */
|
|
83
|
+
export declare const OPERATION_TYPE: Readonly<Record<OperationSlot, string>>;
|
|
84
|
+
/**
|
|
85
|
+
* The modules a `Schema` must come from. The module check is the precision
|
|
86
|
+
* control: a local class called `Schema` is not strawberry's, and matching the
|
|
87
|
+
* bare name would admit it — the same trap `ROUTER_CONSTRUCTORS` guards against
|
|
88
|
+
* for `Blueprint`.
|
|
89
|
+
*/
|
|
90
|
+
export declare const SCHEMA_MODULES: ReadonlySet<string>;
|
|
91
|
+
/** The modules a field constructor must come from, for the same reason. */
|
|
92
|
+
export declare const FIELD_MODULES: ReadonlySet<string>;
|
|
93
|
+
/**
|
|
94
|
+
* The field constructors read as declaring a root operation.
|
|
95
|
+
*
|
|
96
|
+
* Deliberately short. `field` is what netbox's 246 root operations are written
|
|
97
|
+
* with and is the only form with corpus evidence behind it; `mutation` is
|
|
98
|
+
* strawberry's equally unambiguous constructor for the mutation slot, admitted
|
|
99
|
+
* on the same provenance (a resolved import from strawberry) rather than on a
|
|
100
|
+
* name rule. Relay's `node`/`connection` are **not** here: no repository on
|
|
101
|
+
* hand writes them, and a constructor admitted from documentation rather than
|
|
102
|
+
* from a counted repository is a case that was imagined.
|
|
103
|
+
*/
|
|
104
|
+
export declare const FIELD_CONSTRUCTORS: ReadonlySet<string>;
|
|
105
|
+
/** The class decorator that makes a class a GraphQL type at all. */
|
|
106
|
+
export declare const TYPE_DECORATORS: ReadonlySet<string>;
|
|
107
|
+
/**
|
|
108
|
+
* What this run could establish about how strawberry spells a field's name.
|
|
109
|
+
*
|
|
110
|
+
* `"unknown"` is a real and distinct third state, not a synonym for the
|
|
111
|
+
* default: two `StrawberryConfig` calls in one file, or a config passed as a
|
|
112
|
+
* variable, leave the disposition genuinely unresolved. It is kept apart from
|
|
113
|
+
* `"camel"` so the reason a field was refused stays truthful, even though both
|
|
114
|
+
* states refuse the same fields.
|
|
115
|
+
*/
|
|
116
|
+
export type FieldNaming = "verbatim" | "camel" | "unknown";
|
|
117
|
+
/**
|
|
118
|
+
* The schema-facing name of a field, **read** — or `null` when stating it would
|
|
119
|
+
* mean computing it.
|
|
120
|
+
*
|
|
121
|
+
* This function is the whole of the departure-narrowing, and every branch
|
|
122
|
+
* corresponds to a line of strawberry's own `name_converter.py` /
|
|
123
|
+
* `str_converters.py`:
|
|
124
|
+
*
|
|
125
|
+
* - `get_graphql_name` returns `obj.graphql_name` *before* `apply_naming_config`
|
|
126
|
+
* is ever called, so an explicit `name=` is the answer under every config.
|
|
127
|
+
* - with `auto_camel_case=False`, `apply_naming_config` is the identity.
|
|
128
|
+
* - `to_camel_case(s)` is `s.split("_")` rejoined, so for a name containing no
|
|
129
|
+
* `_` it is the identity too — which is why an underscore-free field is
|
|
130
|
+
* readable even when this run could not resolve the config at all.
|
|
131
|
+
*
|
|
132
|
+
* There is no fourth branch, and there must not be one: the only way to answer
|
|
133
|
+
* the remaining case is to run strawberry's transform, and the result would be
|
|
134
|
+
* a string that is not written anywhere in the repository.
|
|
135
|
+
*/
|
|
136
|
+
export declare function readFieldName(attributeName: string, explicitName: string | null, naming: FieldNaming): string | null;
|
|
137
|
+
/** A `strawberry.Schema(...)` call, as the source states it. */
|
|
138
|
+
export interface SchemaDecl {
|
|
139
|
+
readonly file: string;
|
|
140
|
+
readonly line: number;
|
|
141
|
+
/** Slot -> the root class's local name, where it was written as a bare name. */
|
|
142
|
+
readonly roots: ReadonlyMap<OperationSlot, string>;
|
|
143
|
+
/** Slots written as something other than a bare name — disclosed, never guessed. */
|
|
144
|
+
readonly opaqueSlots: readonly {
|
|
145
|
+
readonly slot: OperationSlot;
|
|
146
|
+
readonly written: string;
|
|
147
|
+
}[];
|
|
148
|
+
readonly naming: FieldNaming;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* How this file spells its fields, resolved from the schema call's own `config`.
|
|
152
|
+
*
|
|
153
|
+
* **The tie is syntactic and it is required to be.** `keywordText.config` must
|
|
154
|
+
* literally read `StrawberryConfig(...)`, and the file must contain exactly one
|
|
155
|
+
* `StrawberryConfig` call — otherwise nothing says which config this schema
|
|
156
|
+
* got, and picking one is the guess this reader does not make. A config named
|
|
157
|
+
* by a variable, or one of two, yields `"unknown"`, which costs the snake_case
|
|
158
|
+
* fields and keeps the underscore-free ones (both dispositions agree on those).
|
|
159
|
+
*/
|
|
160
|
+
export declare function namingOf(calls: readonly PyCall[], schemaCall: PyCall): FieldNaming;
|
|
161
|
+
/**
|
|
162
|
+
* Every `strawberry.Schema(...)` this file declares.
|
|
163
|
+
*
|
|
164
|
+
* `strawberry.federation.Schema` is included: federation changes what the
|
|
165
|
+
* gateway does with a subgraph, not how the subgraph names its own operations.
|
|
166
|
+
*/
|
|
167
|
+
export declare function schemaDeclsIn(file: string, calls: readonly PyCall[], moduleOf: (name: string) => string | undefined): readonly SchemaDecl[];
|
|
168
|
+
/** One field on a root operation type, as far as this reader could read it. */
|
|
169
|
+
export interface OperationField {
|
|
170
|
+
readonly attributeName: string;
|
|
171
|
+
/** The schema-facing name, read — or `null` when it would have to be computed. */
|
|
172
|
+
readonly name: string | null;
|
|
173
|
+
readonly file: string;
|
|
174
|
+
readonly line: number;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Is this class-body assignment a declared strawberry field?
|
|
178
|
+
*
|
|
179
|
+
* Provenance, not shape: the constructor's own module must resolve to
|
|
180
|
+
* strawberry or strawberry-django. `helper()` from an unrelated library and a
|
|
181
|
+
* plain `version = "1.0"` are class attributes, not operations.
|
|
182
|
+
*/
|
|
183
|
+
export declare function isFieldConstructor(callee: string | null, moduleOf: (name: string) => string | undefined): boolean;
|
|
184
|
+
/** The literal `name=` on a field constructor, if one was written. */
|
|
185
|
+
export declare function explicitNameOf(keywords: Readonly<Record<string, unknown>>): string | null;
|
|
186
|
+
/** The fields a root operation class declares as class-body assignments. */
|
|
187
|
+
export declare function fieldsFromAttributes(attributes: readonly PyAttribute[], file: string, naming: FieldNaming, moduleOf: (name: string) => string | undefined): readonly OperationField[];
|
|
188
|
+
/**
|
|
189
|
+
* The same field written as a decorated method — `@strawberry.field def
|
|
190
|
+
* circuit_by_id(...)`, strawberry's other documented spelling for a resolver
|
|
191
|
+
* with arguments. `decoratorCalls` carries `@strawberry.field(name="x")`;
|
|
192
|
+
* the bare `@strawberry.field` arrives only in `decorators`, so both are read.
|
|
193
|
+
*/
|
|
194
|
+
export declare function fieldFromMethod(methodName: string, decorators: readonly (string | null)[], decoratorCalls: readonly PyCall[], file: string, line: number, naming: FieldNaming, moduleOf: (name: string) => string | undefined): OperationField | null;
|
|
195
|
+
/** `Query` + `circuit` -> `/Query/circuit`. */
|
|
196
|
+
export declare function operationPath(slot: OperationSlot, fieldName: string): string;
|
|
197
|
+
//# sourceMappingURL=graphql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql.d.ts","sourceRoot":"","sources":["../src/graphql.ts"],"names":[],"mappings":"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"}
|
package/dist/graphql.js
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The GraphQL root-operation extractor for Python — strawberry and
|
|
3
|
+
* strawberry-django.
|
|
4
|
+
*
|
|
5
|
+
* ## The identity, and where it comes from
|
|
6
|
+
*
|
|
7
|
+
* `API_ROUTE`/`API_ENDPOINT` identity is `METHOD /path`, and a GraphQL field has
|
|
8
|
+
* neither a verb nor a URL. `DEC-NEXT-graphql-operation-identity` (descry-core)
|
|
9
|
+
* settles it by transposing the gRPC precedent
|
|
10
|
+
* (`DEC-NEXT-grpc-route-identity`), because deciding it here in isolation is how
|
|
11
|
+
* two producers of one operation end up with two conventions and no join:
|
|
12
|
+
*
|
|
13
|
+
* - **`method` is the literal sentinel `"GRAPHQL"`** — one per protocol, the
|
|
14
|
+
* way gRPC has exactly one `"RPC"` rather than a sentinel per RPC kind. It is
|
|
15
|
+
* not load-bearing for identity (the path alone is unique); it exists so a
|
|
16
|
+
* human or a UI reading `attrs.method` knows not to expect `GET`.
|
|
17
|
+
* - **The path is `/<OperationType>/<field>`** — `/Query/circuit`,
|
|
18
|
+
* `/Mutation/create_order`, `/Subscription/message_added`. GraphQL's root
|
|
19
|
+
* operation type is the structural analogue of gRPC's Service and the field
|
|
20
|
+
* name the analogue of its Method.
|
|
21
|
+
*
|
|
22
|
+
* ## The departure from the precedent, and how it is narrowed
|
|
23
|
+
*
|
|
24
|
+
* gRPC's decision leans on **"the path is read, not assembled"**: protoc writes
|
|
25
|
+
* `Service_Method_FullMethodName = "/pkg.Service/Method"` and the reader takes
|
|
26
|
+
* that literal verbatim. **strawberry writes no such artifact.** The schema is
|
|
27
|
+
* built at import time from the class structure, and the schema-facing field
|
|
28
|
+
* name is not always the Python name:
|
|
29
|
+
*
|
|
30
|
+
* | strawberry's own rule | consequence here |
|
|
31
|
+
* | --- | --- |
|
|
32
|
+
* | `NameConverter.auto_camel_case` defaults to **True** | `circuit_list` is served as `circuitList` |
|
|
33
|
+
* | an explicit `graphql_name` returns before `apply_naming_config` | `field(name="allCircuits")` is the name, verbatim |
|
|
34
|
+
* | `to_camel_case` is `s.split("_")`, rejoined | a name with **no** `_` is unchanged by it |
|
|
35
|
+
*
|
|
36
|
+
* So this reader admits a field **only when its schema-facing name can be read
|
|
37
|
+
* verbatim out of the source** — the three rows above give exactly three such
|
|
38
|
+
* cases, and `readFieldName` is the whole rule. Anything else is refused and
|
|
39
|
+
* disclosed. **The reader never computes a name.** Writing `circuitList` — a
|
|
40
|
+
* string that appears nowhere in the repository — because a library default
|
|
41
|
+
* says it should is precisely the DEC-055 shape both decisions exist to
|
|
42
|
+
* prevent: everything normalises, everything resolves, and the join is silently
|
|
43
|
+
* zero because the consumer half read the real wire name and this half invented
|
|
44
|
+
* a plausible one.
|
|
45
|
+
*
|
|
46
|
+
* The half that *is* still assembled is the `/Query/` prefix, and it is
|
|
47
|
+
* assembled out of the schema call's own slot keyword (`query=`/`mutation=`/
|
|
48
|
+
* `subscription=`) rather than out of any Python name. The three operation-type
|
|
49
|
+
* words are GraphQL's, fixed by the specification, and a client addresses an
|
|
50
|
+
* operation by its slot — never by the root class's name. That is why a class
|
|
51
|
+
* decorated `@strawberry.type(name="Query")` sitting in the `mutation=` slot
|
|
52
|
+
* yields `/Mutation/...` here, and why netbox's ten mixins all decorated
|
|
53
|
+
* `name="Query"` are read through the slot their root occupies rather than
|
|
54
|
+
* through a decorator that strawberry itself discards for a base class.
|
|
55
|
+
*
|
|
56
|
+
* ## The provenance rule, which does the precision work
|
|
57
|
+
*
|
|
58
|
+
* A field becomes an operation only when **a `strawberry.Schema(...)` call,
|
|
59
|
+
* whose callee resolves through the import table to strawberry's own module,
|
|
60
|
+
* puts its class in a root slot.** Not because a class is decorated
|
|
61
|
+
* `@strawberry.type` — netbox has 34 of those and 10 are root mixins — and
|
|
62
|
+
* never because an attribute is spelled like a field. This is `routes.ts`'s
|
|
63
|
+
* "the receiver must resolve to a router constructed from a web framework's own
|
|
64
|
+
* module" rule in a second spelling, and it is the same lesson: a node type
|
|
65
|
+
* comes from provenance or from nothing.
|
|
66
|
+
*
|
|
67
|
+
* The split with `extract.py` is this adapter's standing one — the Python side
|
|
68
|
+
* records syntactic form and names no framework, every decision about what a
|
|
69
|
+
* form *means* is taken here.
|
|
70
|
+
*/
|
|
71
|
+
/**
|
|
72
|
+
* The protocol sentinel. One per protocol, per `DEC-NEXT-grpc-route-identity`'s
|
|
73
|
+
* `"RPC"` — deliberately not split into QUERY/MUTATION/SUBSCRIPTION, because
|
|
74
|
+
* the operation type is carried in the path where gRPC carries the service.
|
|
75
|
+
*/
|
|
76
|
+
export const GRAPHQL_METHOD = "GRAPHQL";
|
|
77
|
+
/** GraphQL's three root operation types, fixed by the specification. */
|
|
78
|
+
export const OPERATION_SLOTS = ["query", "mutation", "subscription"];
|
|
79
|
+
/** The path segment each slot contributes — the specification's own spelling. */
|
|
80
|
+
export const OPERATION_TYPE = {
|
|
81
|
+
query: "Query",
|
|
82
|
+
mutation: "Mutation",
|
|
83
|
+
subscription: "Subscription",
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* The modules a `Schema` must come from. The module check is the precision
|
|
87
|
+
* control: a local class called `Schema` is not strawberry's, and matching the
|
|
88
|
+
* bare name would admit it — the same trap `ROUTER_CONSTRUCTORS` guards against
|
|
89
|
+
* for `Blueprint`.
|
|
90
|
+
*/
|
|
91
|
+
export const SCHEMA_MODULES = new Set([
|
|
92
|
+
"strawberry",
|
|
93
|
+
"strawberry.schema",
|
|
94
|
+
"strawberry.federation",
|
|
95
|
+
"strawberry.federation.schema",
|
|
96
|
+
]);
|
|
97
|
+
/** The modules a field constructor must come from, for the same reason. */
|
|
98
|
+
export const FIELD_MODULES = new Set(["strawberry", "strawberry_django"]);
|
|
99
|
+
/**
|
|
100
|
+
* The field constructors read as declaring a root operation.
|
|
101
|
+
*
|
|
102
|
+
* Deliberately short. `field` is what netbox's 246 root operations are written
|
|
103
|
+
* with and is the only form with corpus evidence behind it; `mutation` is
|
|
104
|
+
* strawberry's equally unambiguous constructor for the mutation slot, admitted
|
|
105
|
+
* on the same provenance (a resolved import from strawberry) rather than on a
|
|
106
|
+
* name rule. Relay's `node`/`connection` are **not** here: no repository on
|
|
107
|
+
* hand writes them, and a constructor admitted from documentation rather than
|
|
108
|
+
* from a counted repository is a case that was imagined.
|
|
109
|
+
*/
|
|
110
|
+
export const FIELD_CONSTRUCTORS = new Set(["field", "mutation"]);
|
|
111
|
+
/** The class decorator that makes a class a GraphQL type at all. */
|
|
112
|
+
export const TYPE_DECORATORS = new Set(["type", "interface", "input"]);
|
|
113
|
+
/**
|
|
114
|
+
* The schema-facing name of a field, **read** — or `null` when stating it would
|
|
115
|
+
* mean computing it.
|
|
116
|
+
*
|
|
117
|
+
* This function is the whole of the departure-narrowing, and every branch
|
|
118
|
+
* corresponds to a line of strawberry's own `name_converter.py` /
|
|
119
|
+
* `str_converters.py`:
|
|
120
|
+
*
|
|
121
|
+
* - `get_graphql_name` returns `obj.graphql_name` *before* `apply_naming_config`
|
|
122
|
+
* is ever called, so an explicit `name=` is the answer under every config.
|
|
123
|
+
* - with `auto_camel_case=False`, `apply_naming_config` is the identity.
|
|
124
|
+
* - `to_camel_case(s)` is `s.split("_")` rejoined, so for a name containing no
|
|
125
|
+
* `_` it is the identity too — which is why an underscore-free field is
|
|
126
|
+
* readable even when this run could not resolve the config at all.
|
|
127
|
+
*
|
|
128
|
+
* There is no fourth branch, and there must not be one: the only way to answer
|
|
129
|
+
* the remaining case is to run strawberry's transform, and the result would be
|
|
130
|
+
* a string that is not written anywhere in the repository.
|
|
131
|
+
*/
|
|
132
|
+
export function readFieldName(attributeName, explicitName, naming) {
|
|
133
|
+
if (explicitName !== null && explicitName !== "")
|
|
134
|
+
return explicitName;
|
|
135
|
+
if (naming === "verbatim")
|
|
136
|
+
return attributeName;
|
|
137
|
+
return attributeName.includes("_") ? null : attributeName;
|
|
138
|
+
}
|
|
139
|
+
/** The leading dotted segment of a callee — `strawberry` in `strawberry.Schema`. */
|
|
140
|
+
function rootSegmentOf(callee) {
|
|
141
|
+
const dot = callee.indexOf(".");
|
|
142
|
+
return dot === -1 ? callee : callee.slice(0, dot);
|
|
143
|
+
}
|
|
144
|
+
/** The trailing segment — `Schema` in `strawberry.federation.Schema`. */
|
|
145
|
+
function lastSegmentOf(callee) {
|
|
146
|
+
const dot = callee.lastIndexOf(".");
|
|
147
|
+
return dot === -1 ? callee : callee.slice(dot + 1);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Does a written callee resolve, through the file's import table, to a symbol
|
|
151
|
+
* in one of `modules`?
|
|
152
|
+
*
|
|
153
|
+
* Both spellings are accepted and both are checked: `from strawberry import
|
|
154
|
+
* Schema` binds the symbol directly, and `import strawberry` binds the module,
|
|
155
|
+
* in which case the dotted prefix in the source carries the rest of the path.
|
|
156
|
+
*/
|
|
157
|
+
function resolvesToModule(callee, wanted, modules, moduleOf) {
|
|
158
|
+
if (!wanted.has(lastSegmentOf(callee)))
|
|
159
|
+
return false;
|
|
160
|
+
const root = rootSegmentOf(callee);
|
|
161
|
+
const bound = moduleOf(root);
|
|
162
|
+
if (bound === undefined)
|
|
163
|
+
return false;
|
|
164
|
+
// `from strawberry import Schema` -> bound is `strawberry`, callee is `Schema`.
|
|
165
|
+
if (root === callee)
|
|
166
|
+
return modules.has(bound);
|
|
167
|
+
// `import strawberry` -> bound is `strawberry`, callee is `strawberry.Schema`;
|
|
168
|
+
// the dotted middle is part of the module path, so rebuild and check it.
|
|
169
|
+
const middle = callee.slice(root.length + 1, callee.length - lastSegmentOf(callee).length - 1);
|
|
170
|
+
const full = middle === "" ? bound : `${bound}.${middle}`;
|
|
171
|
+
return modules.has(full);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* How this file spells its fields, resolved from the schema call's own `config`.
|
|
175
|
+
*
|
|
176
|
+
* **The tie is syntactic and it is required to be.** `keywordText.config` must
|
|
177
|
+
* literally read `StrawberryConfig(...)`, and the file must contain exactly one
|
|
178
|
+
* `StrawberryConfig` call — otherwise nothing says which config this schema
|
|
179
|
+
* got, and picking one is the guess this reader does not make. A config named
|
|
180
|
+
* by a variable, or one of two, yields `"unknown"`, which costs the snake_case
|
|
181
|
+
* fields and keeps the underscore-free ones (both dispositions agree on those).
|
|
182
|
+
*/
|
|
183
|
+
export function namingOf(calls, schemaCall) {
|
|
184
|
+
const written = schemaCall.keywordText["config"];
|
|
185
|
+
// No config keyword at all: strawberry's documented default, verified against
|
|
186
|
+
// `NameConverter.__init__` — `auto_camel_case` is True.
|
|
187
|
+
if (written === undefined)
|
|
188
|
+
return "camel";
|
|
189
|
+
if (!/^\s*(?:[A-Za-z_][\w.]*\.)?StrawberryConfig\s*\(/.test(written))
|
|
190
|
+
return "unknown";
|
|
191
|
+
const configs = calls.filter((c) => c.callee !== null && lastSegmentOf(c.callee) === "StrawberryConfig");
|
|
192
|
+
if (configs.length !== 1)
|
|
193
|
+
return "unknown";
|
|
194
|
+
const value = configs[0].keywords["auto_camel_case"];
|
|
195
|
+
if (value === true)
|
|
196
|
+
return "camel";
|
|
197
|
+
if (value === false)
|
|
198
|
+
return "verbatim";
|
|
199
|
+
// Written, but not as a literal — or not written, in which case the
|
|
200
|
+
// constructor default applies and that default is camel-casing.
|
|
201
|
+
return configs[0].opaqueKeywords.includes("auto_camel_case") ? "unknown" : "camel";
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Every `strawberry.Schema(...)` this file declares.
|
|
205
|
+
*
|
|
206
|
+
* `strawberry.federation.Schema` is included: federation changes what the
|
|
207
|
+
* gateway does with a subgraph, not how the subgraph names its own operations.
|
|
208
|
+
*/
|
|
209
|
+
export function schemaDeclsIn(file, calls, moduleOf) {
|
|
210
|
+
const found = [];
|
|
211
|
+
for (const call of calls) {
|
|
212
|
+
if (call.callee === null)
|
|
213
|
+
continue;
|
|
214
|
+
if (!resolvesToModule(call.callee, new Set(["Schema"]), SCHEMA_MODULES, moduleOf))
|
|
215
|
+
continue;
|
|
216
|
+
const roots = new Map();
|
|
217
|
+
const opaqueSlots = [];
|
|
218
|
+
for (const slot of OPERATION_SLOTS) {
|
|
219
|
+
const bare = call.keywordNames[slot];
|
|
220
|
+
if (bare !== undefined) {
|
|
221
|
+
roots.set(slot, bare);
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
const written = call.keywordText[slot];
|
|
225
|
+
// A slot written as a call, a subscript or an attribute names a root this
|
|
226
|
+
// reader cannot follow. The operations under it are real and unreadable —
|
|
227
|
+
// the exact thing a ledger row is for.
|
|
228
|
+
if (written !== undefined)
|
|
229
|
+
opaqueSlots.push({ slot, written });
|
|
230
|
+
}
|
|
231
|
+
if (roots.size === 0 && opaqueSlots.length === 0)
|
|
232
|
+
continue;
|
|
233
|
+
found.push({ file, line: call.line, roots, opaqueSlots, naming: namingOf(calls, call) });
|
|
234
|
+
}
|
|
235
|
+
return found;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Is this class-body assignment a declared strawberry field?
|
|
239
|
+
*
|
|
240
|
+
* Provenance, not shape: the constructor's own module must resolve to
|
|
241
|
+
* strawberry or strawberry-django. `helper()` from an unrelated library and a
|
|
242
|
+
* plain `version = "1.0"` are class attributes, not operations.
|
|
243
|
+
*/
|
|
244
|
+
export function isFieldConstructor(callee, moduleOf) {
|
|
245
|
+
if (callee === null)
|
|
246
|
+
return false;
|
|
247
|
+
return resolvesToModule(callee, FIELD_CONSTRUCTORS, FIELD_MODULES, moduleOf);
|
|
248
|
+
}
|
|
249
|
+
/** The literal `name=` on a field constructor, if one was written. */
|
|
250
|
+
export function explicitNameOf(keywords) {
|
|
251
|
+
const name = keywords["name"];
|
|
252
|
+
return typeof name === "string" ? name : null;
|
|
253
|
+
}
|
|
254
|
+
/** The fields a root operation class declares as class-body assignments. */
|
|
255
|
+
export function fieldsFromAttributes(attributes, file, naming, moduleOf) {
|
|
256
|
+
const fields = [];
|
|
257
|
+
for (const attribute of attributes) {
|
|
258
|
+
if (!isFieldConstructor(attribute.callee, moduleOf))
|
|
259
|
+
continue;
|
|
260
|
+
const explicit = explicitNameOf(attribute.keywords);
|
|
261
|
+
fields.push({
|
|
262
|
+
attributeName: attribute.name,
|
|
263
|
+
name: readFieldName(attribute.name, explicit, naming),
|
|
264
|
+
file,
|
|
265
|
+
line: attribute.line,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
return fields;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* The same field written as a decorated method — `@strawberry.field def
|
|
272
|
+
* circuit_by_id(...)`, strawberry's other documented spelling for a resolver
|
|
273
|
+
* with arguments. `decoratorCalls` carries `@strawberry.field(name="x")`;
|
|
274
|
+
* the bare `@strawberry.field` arrives only in `decorators`, so both are read.
|
|
275
|
+
*/
|
|
276
|
+
export function fieldFromMethod(methodName, decorators, decoratorCalls, file, line, naming, moduleOf) {
|
|
277
|
+
let explicit = null;
|
|
278
|
+
let matched = false;
|
|
279
|
+
for (const decorator of decoratorCalls) {
|
|
280
|
+
if (!isFieldConstructor(decorator.callee, moduleOf))
|
|
281
|
+
continue;
|
|
282
|
+
matched = true;
|
|
283
|
+
explicit = explicitNameOf(decorator.keywords) ?? explicit;
|
|
284
|
+
}
|
|
285
|
+
if (!matched) {
|
|
286
|
+
for (const written of decorators) {
|
|
287
|
+
// `@strawberry.field(name="x")` is recorded here too, as source text.
|
|
288
|
+
// Strip any call so the bare and called forms take one path.
|
|
289
|
+
const bare = written === null ? null : written.replace(/\s*\(.*$/s, "");
|
|
290
|
+
if (bare !== null && isFieldConstructor(bare, moduleOf))
|
|
291
|
+
matched = true;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (!matched)
|
|
295
|
+
return null;
|
|
296
|
+
return { attributeName: methodName, name: readFieldName(methodName, explicit, naming), file, line };
|
|
297
|
+
}
|
|
298
|
+
/** `Query` + `circuit` -> `/Query/circuit`. */
|
|
299
|
+
export function operationPath(slot, fieldName) {
|
|
300
|
+
return `/${OPERATION_TYPE[slot]}/${fieldName}`;
|
|
301
|
+
}
|
|
302
|
+
//# sourceMappingURL=graphql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphql.js","sourceRoot":"","sources":["../src/graphql.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@descryy/adapter-python` — the Python language adapter.
|
|
3
|
+
*
|
|
4
|
+
* Depends on `@descryy/ir` and `@descryy/adapter-common`, and on nothing else in
|
|
5
|
+
* the engine. Parsing is Python's own `ast`, in one subprocess (DEC-062).
|
|
6
|
+
*/
|
|
7
|
+
export { ADAPTER_ID, ADAPTER_VERSION, DEFAULT_PYTHON_GLOBS, LANGUAGE, createPythonAdapter, hashOf, } from "./adapter.ts";
|
|
8
|
+
export type { PythonAdapter, PythonAdapterOptions } from "./adapter.ts";
|
|
9
|
+
export { importRoots, modulePathOf, moduleNameOf, projectName, resolveImport, } from "./module.ts";
|
|
10
|
+
export type { ImportRecord, ImportTarget, ResolveOptions } from "./module.ts";
|
|
11
|
+
export { readPytestConfig, globToRegExp, PYTEST_DEFAULTS } from "./pytest-config.ts";
|
|
12
|
+
export type { PytestConfig } from "./pytest-config.ts";
|
|
13
|
+
export { DECLARATIVE_BASE_FACTORIES, ORM_BASE_MODULES, isColumnCall, isFrameworkBaseName, ormShapeOf, } from "./orm.ts";
|
|
14
|
+
export type { OrmField, OrmFramework, OrmShape, PyAttribute } from "./orm.ts";
|
|
15
|
+
export { GRAPHQL_METHOD, OPERATION_SLOTS, OPERATION_TYPE, namingOf, operationPath, readFieldName, schemaDeclsIn, } from "./graphql.ts";
|
|
16
|
+
export type { FieldNaming, OperationField, OperationSlot, SchemaDecl } from "./graphql.ts";
|
|
17
|
+
export { extract } from "./extract.ts";
|
|
18
|
+
export type { ExtractInput, Extraction, PyResult } from "./extract.ts";
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,UAAU,EACV,eAAe,EACf,oBAAoB,EACpB,QAAQ,EACR,mBAAmB,EACnB,MAAM,GACP,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAExE,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9E,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrF,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,UAAU,GACX,MAAM,UAAU,CAAC;AAClB,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE9E,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,EACd,QAAQ,EACR,aAAa,EACb,aAAa,EACb,aAAa,GACd,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE3F,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@descryy/adapter-python` — the Python language adapter.
|
|
3
|
+
*
|
|
4
|
+
* Depends on `@descryy/ir` and `@descryy/adapter-common`, and on nothing else in
|
|
5
|
+
* the engine. Parsing is Python's own `ast`, in one subprocess (DEC-062).
|
|
6
|
+
*/
|
|
7
|
+
export { ADAPTER_ID, ADAPTER_VERSION, DEFAULT_PYTHON_GLOBS, LANGUAGE, createPythonAdapter, hashOf, } from "./adapter.js";
|
|
8
|
+
export { importRoots, modulePathOf, moduleNameOf, projectName, resolveImport, } from "./module.js";
|
|
9
|
+
export { readPytestConfig, globToRegExp, PYTEST_DEFAULTS } from "./pytest-config.js";
|
|
10
|
+
export { DECLARATIVE_BASE_FACTORIES, ORM_BASE_MODULES, isColumnCall, isFrameworkBaseName, ormShapeOf, } from "./orm.js";
|
|
11
|
+
export { GRAPHQL_METHOD, OPERATION_SLOTS, OPERATION_TYPE, namingOf, operationPath, readFieldName, schemaDeclsIn, } from "./graphql.js";
|
|
12
|
+
export { extract } from "./extract.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,UAAU,EACV,eAAe,EACf,oBAAoB,EACpB,QAAQ,EACR,mBAAmB,EACnB,MAAM,GACP,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrF,OAAO,EACL,0BAA0B,EAC1B,gBAAgB,EAChB,YAAY,EACZ,mBAAmB,EACnB,UAAU,GACX,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,cAAc,EACd,eAAe,EACf,cAAc,EACd,QAAQ,EACR,aAAa,EACb,aAAa,EACb,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
|