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

awscdk-appsync-decorators

v0.0.6

Published

Decorators for creating appsync apis using aws-cdk

Readme

AWS CDK AppSync Decorators

Provides decorators for creating appsync apis using aws-cdk and awscdk-appsync-utils.

More information can be found here.

Code First Schema

A SchemaBinder is used to generate a CodeFirstSchema.

const binder = new SchemaBinder();
const api = new GraphqlApi(this, 'Api', {
    name: 'Demo',
    definition: Definition.fromSchema(binder.schema),
});

binder.addQuery(Query);
binder.addMutation(Mutation);
binder.addSubscription(Subscription);

binder.bindSchema();

Types

The foundations of a schema are it's type definitions.

Scalar

The built-in scalar types can be accessed via the Scalar enum (e.g. Scalar.ID, Scalar.AWS_DATE).

Interface

The @InterfaceType() decorator is attached to a class that defines the interface shape.

@InterfaceType()
class Node {
    id = Scalar.STRING;
}

GraphQL

interface Node {
    id: String
}

Object

The @ObjectType() decorator is attached to a class that defines the object shape.

If an object implements any interfaces, then the interface class types should be provided to the decorator.

@InterfaceType()
class Node {
    id = Scalar.STRING;
}

@ObjectType(Node)
class FilmNode {
    filmName = Scalar.STRING;
}

GraphQL

interface Node {
    id: String
}

type FilmNode implements Node {
    filmName: String
}

Enum

The @EnumType() decorator is attached to a class that defines the enum values.

The property names are used as the enum values and the property values are ignored (so can be anything to keep TypeScript happy).

@EnumType()
class Episode {
    NEWHOPE = Scalar.STRING;
    EMPIRE = Scalar.STRING;
    JEDI = Scalar.STRING;
}

GraphQL

enum Episode {
    NEWHOPE
    EMPIRE
    JEDI
}

Input

The @InputType() decorator is attached to a class that defines the input shape.

@InputType()
class Review {
    stars = Scalar.INT;
    commentary = Scalar.STRING;
}

GraphQL

input Review {
    stars: Int
    commentary: String
}

Union

The @UnionType() decorator is attached to a class that defines the union.

All object class types should be provided to the decorator.

@ObjectType()
class Human {
    name = Scalar.STRING;
}

@ObjectType()
class Droid {
    name = Scalar.STRING;
}

@ObjectType()
class Starship {
    name = Scalar.STRING;
}

@UnionType(Human, Droid, Starship)
class Search {}

GraphQL

union Search = Human | Droid | Starship

Args

The @Args() decorator is attached to a property and provides a class type that defines the argument names and types.

class FilmArgs {
    after = Scalar.STRING;
    first = Scalar.INT;
    before = Scalar.STRING;
    last = Scalar.INT;
}

class Query {
    @Args(FilmArgs)
    allFilms = FilmConnection;
}

GraphQL

type Query {
    allFilms(after: String, first: Int, before: String, last: Int): FilmConnection
}

Modifiers

Modifiers can be attached to properties to define when a value is a list or non-null.

  • @List()
  • @Required()
  • @RequiredList()

If the @RequiredList() decorator is attached, then the @List() decorator is not needed.

A property is also considered a list when it's return type is an array.

class FilmArgs {
    @Required()
    id = Scalar.STRING;
}

@ObjectType()
class Film {
    @Required()
    id = Scalar.STRING;

    @Required()
    filmName = Scalar.STRING;

    @List()
    reviews = Review; // can also be Review[] as an alternative
}

class Query {
    @Args(FilmArgs)
    @Required()
    film = Film;
}

GraphQL

type Film {
    id: String!
    filmName: String!
    reviews: [Review]
}

type Query {
    film(id: String!): Film!
}

Resolvers

Resolvers are defined by extending either JsResolver or VtlResolver and then using the @Resolver() decorator to attach them to properties.

Under the hood, when defining the resolver class, a data source definition is required. As a result, when calling bindSchema(), the relevant data source definitions should be included to match the name provided by the resolver.

class FilmResolver extends JsResolver {
    dataSource = 'Demo';
    code = Code.fromInline('...code...');
}

class AllFilmsResolver extends VtlResolver {
    dataSource = 'Demo';
    requestMappingTemplate = MappingTemplate.fromString('...template...');
    responseMappingTemplate = MappingTemplate.fromString('...template...');
}

class Query {
    @Resolver(FilmResolver)
    film = Film;

    @Resolver(AllFilmsResolver)
    allFilms = Film[];
}

// Bind the schema
const dataSource = api.addNoneDataSource('NoneDataSource');

binder.bindSchema({
    dataSources: {
        'Demo': dataSource,
    },
});

If a resolver pipeline is needed, then an array of function names can be provided to the decorator. Note that a data source should not be provided for a pipeline resolver.

As with the data sources, the named function definitions should be included when calling bindSchema().

class AddFilmResolver extends JsResolver {
    code = Code.fromInline('...code...');
}

class Mutation {
    @Resolver(AddFilmResolver, 'Index', 'Db')
    addFilm = Film;
}

// Bind the schema
const indexFunction = new appsync.AppsyncFunction(this, 'IndexFunction');
const dbFunction = new appsync.AppsyncFunction(this, 'DbFunction');

binder.bindSchema({
    functions: {
        Index: indexFunction,
        Db: dbFunction,
    },
});

Directives

Directives can be attached to both classes and properties.

  • @ApiKey()
  • @Cognito(groups)
  • @Custom(statement)
  • @Iam()
  • @Lambda()
  • @Oidc()
  • @Subscribe(mutations)

Caching

When a resolver is attached to a property, then a caching configuration can also be attached using the @Cache() decorator. This accepts a time to live (TTL) value in seconds and an optional array of keys.

class Query {
    @Args(FilmArgs)
    @Resolver(FilmResolver)
    @Cache(30)
    film = Film;
}