@suss/contract-appsync 0.20.0 → 0.21.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 +92 -0
- package/package.json +4 -4
package/README.md
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# @suss/contract-appsync
|
|
2
|
+
|
|
3
|
+
Generate suss `BehavioralSummary[]` from an [AWS AppSync](https://docs.aws.amazon.com/appsync/) API declared in a CloudFormation or [SAM](https://aws.amazon.com/serverless/sam/) template. AppSync is schema-first: the SDL is authored by hand and the template binds each `(TypeName, FieldName)` pair to a data source. This reader turns that wiring into resolver summaries you can check consumers against, without deploying the stack or exporting anything from AWS.
|
|
4
|
+
|
|
5
|
+
## What this package reads
|
|
6
|
+
|
|
7
|
+
`@suss/contract-appsync` walks the template's `Resources` map and covers both ways an AppSync API gets written:
|
|
8
|
+
|
|
9
|
+
- **Raw resources**: `AWS::AppSync::GraphQLApi`, `AWS::AppSync::GraphQLSchema`, `AWS::AppSync::Resolver`, `AWS::AppSync::FunctionConfiguration`, and `AWS::AppSync::DataSource`.
|
|
10
|
+
- **The SAM shorthand** `AWS::Serverless::GraphQLApi`, whose inline `SchemaInline` / `SchemaUri`, `DataSources`, `Functions`, and `Resolvers` blocks are normalized into the same model before any summary is built. Synthesized logical ids are prefixed with the API's logical id, so two GraphQL APIs in one template stay apart.
|
|
11
|
+
|
|
12
|
+
The SDL comes from the inline `Definition` / `SchemaInline` property, or from a local file when `DefinitionS3Location` / `SchemaUri` is a path (resolved against the template's directory). An `s3://` or `http(s)://` URI cannot be fetched by a static reader, and neither can a location the template computes through an intrinsic. Both cases are recorded under `metadata.appsync.schemaSource` with a `status` of `"unresolved"` and a reason, so a schema the reader could not open is never silent.
|
|
13
|
+
|
|
14
|
+
## What it produces
|
|
15
|
+
|
|
16
|
+
One `resolver`-kind summary per resolver, plus one `library`-kind summary per API whose SDL resolved.
|
|
17
|
+
|
|
18
|
+
Each resolver summary has:
|
|
19
|
+
|
|
20
|
+
- `identity.name`: `Type.field`, and a `graphql-resolver` boundary binding with `transport: "aws-https"`, `recognition: "appsync"`, plus the type and field names. That pairs against resolvers the Apollo and NestJS packs extract from code, and against clients that cross the same field.
|
|
21
|
+
- Inputs from the SDL field's arguments, each with `role: "args"` and the argument's type converted to a suss `TypeShape`.
|
|
22
|
+
- Two transitions: a default success returning the field's declared shape, and a generic throw for the GraphQL `errors[]` path.
|
|
23
|
+
- `metadata.appsync`: the API's logical id and name, the data source's logical id, the Lambda function behind that data source, the resolver kind (`UNIT` or `PIPELINE`), the authentication type, the `CodeUri` and runtime for SAM resolvers written as JS or VTL, whether the schema declared the field (`schemaMatched`), and, for pipeline resolvers, the ordered function chain with each step's own data source and Lambda.
|
|
24
|
+
|
|
25
|
+
A resolver whose field the SDL never declares still gets a summary. AppSync rejects that stack at deploy time, and reporting the boundary is more useful than dropping it. Its success transition returns `unknown` and `schemaMatched` is `false`.
|
|
26
|
+
|
|
27
|
+
The `library` summary is where the SDL itself goes. Type definitions belong to the schema rather than to any one field, so each resolver points at that document through a source-document label, and the checker follows the label to resolve a consumer's nested selections against the resolver's return type. It binds to no boundary, so pairing records it as taking no part.
|
|
28
|
+
|
|
29
|
+
Data source types are normalized from `AWS_LAMBDA`, `AMAZON_DYNAMODB`, `AMAZON_ELASTICSEARCH`, `AMAZON_OPENSEARCH_SERVICE`, `HTTP`, `RELATIONAL_DATABASE`, `AMAZON_EVENTBRIDGE`, and `NONE`. Anything else comes back as `"unknown"`.
|
|
30
|
+
|
|
31
|
+
## What it does not read
|
|
32
|
+
|
|
33
|
+
- **Resolver code.** A SAM resolver's `CodeUri` and runtime are recorded, and the file behind them is never opened. VTL request and response mapping templates on raw `AWS::AppSync::Resolver` resources are ignored.
|
|
34
|
+
- **Dynamic intrinsics.** A resolver whose `TypeName` or `FieldName` comes from a `!Ref` or an `Fn::Join` is skipped rather than guessed at. A pipeline whose `Functions` array cannot be resolved statically still reports `kind: "PIPELINE"` with an empty chain.
|
|
35
|
+
- **Remote schemas.** Nothing is fetched over the network.
|
|
36
|
+
- **Authorization.** The API's `AuthenticationType` is recorded on each resolver and does not become extra transitions.
|
|
37
|
+
- **Nested stacks.** Only the template you point at is walked.
|
|
38
|
+
|
|
39
|
+
## Worked example
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
Resources:
|
|
43
|
+
Api:
|
|
44
|
+
Type: AWS::AppSync::GraphQLApi
|
|
45
|
+
Properties:
|
|
46
|
+
Name: orders
|
|
47
|
+
AuthenticationType: API_KEY
|
|
48
|
+
Schema:
|
|
49
|
+
Type: AWS::AppSync::GraphQLSchema
|
|
50
|
+
Properties:
|
|
51
|
+
ApiId: !GetAtt Api.ApiId
|
|
52
|
+
Definition: |
|
|
53
|
+
type Order { id: ID!, total: Float! }
|
|
54
|
+
type Query { order(id: ID!): Order }
|
|
55
|
+
OrderResolver:
|
|
56
|
+
Type: AWS::AppSync::Resolver
|
|
57
|
+
Properties:
|
|
58
|
+
ApiId: !GetAtt Api.ApiId
|
|
59
|
+
TypeName: Query
|
|
60
|
+
FieldName: order
|
|
61
|
+
DataSourceName: !Ref OrdersLambda
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
suss contract --from appsync template.yaml -o summaries/appsync.json
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
That gives a `Query.order` resolver summary with one `id` input of type `ID`, a success transition returning a `ref` to `Order`, and the SDL under the API's schema document summary.
|
|
69
|
+
|
|
70
|
+
Or programmatically, when you already have the template in memory (a CDK `Template.fromStack`, JSON from a build tool):
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import { appsyncToSummaries } from "@suss/contract-appsync";
|
|
74
|
+
|
|
75
|
+
const summaries = appsyncToSummaries(template, { baseDir: "infra" });
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Where it fits in suss
|
|
79
|
+
|
|
80
|
+
Depends on `@suss/behavioral-ir` (for the IR types it produces), `@suss/contract-graphql` (for SDL parsing, the type conversion, and loading an external schema file), `@suss/manifest-aws` (for template loading, including CloudFormation YAML intrinsic shorthand), and `graphql`. It does not extract from source code and is independent of the language adapters.
|
|
81
|
+
|
|
82
|
+
## Coverage
|
|
83
|
+
|
|
84
|
+

|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
Licensed under Apache 2.0. See [LICENSE](../../../LICENSE).
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
For the format the summaries conform to, see [`docs/behavioral-summary-format.md`](../../../docs/behavioral-summary-format.md). For the schema-only counterpart that reads a plain SDL file, see [`@suss/contract-graphql`](../graphql/README.md).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@suss/contract-appsync",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.21.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Generate suss behavioral summaries from AWS AppSync in CloudFormation (AWS::AppSync::*) and SAM (AWS::Serverless::GraphQLApi) templates, including external .graphql schema files (GraphQL schema-first).",
|
|
6
6
|
"keywords": [
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
"typecheck": "tsc --noEmit"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@suss/behavioral-ir": "0.
|
|
50
|
-
"@suss/contract-graphql": "0.
|
|
51
|
-
"@suss/manifest-aws": "0.
|
|
49
|
+
"@suss/behavioral-ir": "0.21.0",
|
|
50
|
+
"@suss/contract-graphql": "0.21.0",
|
|
51
|
+
"@suss/manifest-aws": "0.21.0",
|
|
52
52
|
"graphql": "^16.8.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|