npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@suss/contract-appsync

v0.38.2

Published

Turn the AppSync API in a CloudFormation or SAM template into a suss contract and check it against the resolvers and clients on either side of it.

Readme

@suss/contract-appsync

Part of suss, which reads both sides of every call in a repository and reports where the two disagree.

This package builds suss BehavioralSummary[] from an AWS AppSync API declared in a CloudFormation or SAM template. AppSync is schema-first: you write the SDL 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.

What this package reads

@suss/contract-appsync walks the template's Resources map, and covers both ways of writing an AppSync API:

  • Raw resources: AWS::AppSync::GraphQLApi, AWS::AppSync::GraphQLSchema, AWS::AppSync::Resolver, AWS::AppSync::FunctionConfiguration and AWS::AppSync::DataSource.
  • The SAM shorthand AWS::Serverless::GraphQLApi. Its inline SchemaInline / SchemaUri, DataSources, Functions and Resolvers blocks are converted into the same model before any summary is built. Generated logical ids are prefixed with the API's logical id, so two GraphQL APIs in one template stay apart.

A resolver or a pipeline function can point at its data source by logical id or by the data source's Name. A name is looked up among the data sources of the same API, so two APIs can each have a data source called orders.

The reader also reads every template the file embeds through an AWS::CloudFormation::Stack or AWS::Serverless::Application, and treats them as one API surface. A child's resources get the stack path in front of their logical id, as in DirectoryStack/DirectoryFunction, the same id the aws-lambda pack gives that function. When a parent passes a resource to a child as a parameter, such as ApiId: !GetAtt Api.ApiId, the child's !Ref ApiId reads as that resource, so a child's resolvers attach to the API and schema the root declares. A child it cannot open is reported by name.

The SDL comes from the inline Definition / SchemaInline property, or from a local file when DefinitionS3Location / SchemaUri is a path, resolved against the directory of the template that declares it. A static reader cannot fetch an s3:// or http(s):// URI, or a location the template computes with 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 always reported.

What it produces

One resolver-kind summary per resolver, plus one library-kind summary per API whose SDL resolved.

Each resolver summary has:

  • identity.name: Type.field, and a graphql-resolver boundary binding with transport: "aws-https", recognition: "appsync", and the type and field names. It pairs with resolvers that the Apollo and NestJS packs extract from code, and with clients that use the same field.
  • Inputs from the SDL field's arguments, each with role: "args" and the argument's type converted to a suss TypeShape.
  • Two transitions: a default success that returns the field's declared shape, and a generic throw for the GraphQL errors[] path.
  • 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), and the authentication type. For SAM resolvers written as JS or VTL it also has the CodeUri and runtime. It records whether the schema declared the field (schemaMatched), and for pipeline resolvers, the ordered chain of functions, with each step's own data source and Lambda.

A resolver whose field the SDL never declares still gets a summary. AppSync rejects that stack at deploy time, so reporting the boundary helps more than dropping it. Its success transition returns unknown, and schemaMatched is false.

The library summary contains the SDL itself. Type definitions belong to the schema as a whole, so each resolver points at that document through a source-document label. The checker follows the label to resolve a consumer's nested selections against the resolver's return type. The library summary does not bind to a boundary, so pairing records it as taking no part.

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".

What it does not read

  • Resolver code. A SAM resolver's CodeUri and runtime are recorded, but the file behind them is never opened. VTL request and response mapping templates on raw AWS::AppSync::Resolver resources are ignored.
  • Dynamic intrinsics. A resolver whose TypeName or FieldName comes from a !Ref or an Fn::Join is skipped, so the reader never guesses. A pipeline whose Functions array cannot be resolved statically still reports kind: "PIPELINE", with an empty chain.
  • Remote schemas. Nothing is fetched over the network.
  • Authorization. The API's AuthenticationType is recorded on each resolver, and does not add transitions.
  • Stack outputs. A parent that reads a child's resource through !GetAtt Child.Outputs.X points at nothing the reader follows.

Worked example

Resources:
  Api:
    Type: AWS::AppSync::GraphQLApi
    Properties:
      Name: orders
      AuthenticationType: API_KEY
  Schema:
    Type: AWS::AppSync::GraphQLSchema
    Properties:
      ApiId: !GetAtt Api.ApiId
      Definition: |
        type Order { id: ID!, total: Float! }
        type Query { order(id: ID!): Order }
  OrderResolver:
    Type: AWS::AppSync::Resolver
    Properties:
      ApiId: !GetAtt Api.ApiId
      TypeName: Query
      FieldName: order
      DataSourceName: !Ref OrdersLambda
suss contract --from appsync template.yaml -o summaries/appsync.json

That produces a Query.order resolver summary with one id input of type ID and a success transition that returns a ref to Order. The SDL goes in the API's schema document summary.

If you already have the template in memory, such as a CDK Template.fromStack or JSON from a build tool, call it from code:

import { appsyncToSummaries } from "@suss/contract-appsync";

const summaries = appsyncToSummaries(template, { baseDir: "infra" });

Where it fits in suss

The package depends on @suss/behavioral-ir for the IR types it produces, @suss/contract-graphql for SDL parsing, type conversion and loading an external schema file, @suss/manifest-aws for loading templates (including CloudFormation's YAML shorthand for intrinsics), and graphql. It does not extract from source code and does not use the language adapters.

More

Coverage

coverage

License

Licensed under Apache 2.0. See LICENSE.


For the format the summaries conform to, see docs/reference/summary-format.md. For the schema-only counterpart that reads a plain SDL file, see @suss/contract-graphql.