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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@rxr/amplify-orm

v1.2.15

Published

Use like:

Downloads

7

Readme

Amplify ORM

Building

Use like:

node scripts/build [config file] [output directory]

i.e.: node scripts/build ./amplify-orm.config.js ./build

Before you run the build script, make sure your compiled schema is up to date using amplify api gql-compile

Output

The output will be a folder with a bunch of models

Requirements

  • node ^14.14.0

RunTime

Project Dependencies

  • "graphql-tag": "^2.12.6"

Initialization

Before you can use the collections, you must first initialize the data layer using the collections/index -> init function. This function takes a single argument: the Amplify config file. It's recommended to initialize your collections as soon as possible after authentication is established.

Example initialization call:

const AWSAppSyncClient = require('aws-appsync').default
const config = require('../src/aws-exports.js')
const {init} = require('../build/collections')

const client = new AWSAppSyncClient(
  {
    url: config.aws_appsync_graphqlEndpoint,
    region: config.aws_appsync_region,
    auth: {
      type: 'AMAZON_COGNITO_USER_POOLS',
      jwtToken: '/* Your auth Token */',
    },
    disableOffline: true,
  }
)

// handle session/token refresh in this callback function
init(() => client)

Using Collections

Use like:

const {Post} = require('./build/collections')

//....

// load all posts with all fields (excluding connections)
const allPosts = await Post.listPosts()

// using a custom fragment
const allPostsWithAuthor = await Post.as(Post.WithAuthor).listPosts()

// using an indexed query
const myPosts = await Post.listPostsByAuthor({authorId: 'xxxx'})

// combining fragment and query to load all posts with author data in last 24 hours
const recentPosts = await Post.as(Post.WithAuthor).listPosts({
  input: {
    createdAt: {
      gt: new Date(Date.now() - 86400000)
    }
  }
})

Configuration

Custom Fragments

Fragments define the structure of the response payload. You can define custom fragments (name and payload) by setting the fragments field on your config object.

The fragments object is multi-dimensional map that follows a Model -> Fragment Name -> Fields hierarchy. For example:

const fragments = {
  User: {
    ProfileOnly: ['firstName', 'lastName', 'birthday'],
  },
}

This would generate a GraphQL fragment like:

fragment UserProfileOnly on User {
    firstName
    lastName
    birthday
}

Nested payloads

Every collection's default fragment includes all fields and excludes all connections. Custom Fragments can be defined to include associated models.

Include an object keyed by connection name with a value including the fields of that model you'd like to query. Multiple models can be defined in a single object. And this pattern can be nested to include connections on related models as well. For example:

const fragments = {
  User: {
    WithEmployer: [
      'id', 
      'firstName', 
      {
        employer: [
          'id',
          'address',
          {
            industry: [
              'id',
              'label'
            ],
            // products is a one-to-many connection, but its definition is the same as a one-to-one connection
            products: [
              'id',
              'label'
            ]
          }
        ]
      }
    ],
  },
}

This would generate a GraphQL fragment like:

fragment UserWithEmployer on User {
    id
    firstName
    employer {
        id
        address
        industry {
            id
            label
        }
        products {
           items {
               id
               label
           } 
           nextToken
        }
    }
}

Notice the one to many association between employer and products is handled automatically and abstracted from the fragment definition.

Module syntax

By default, the exported collections use CommonJS syntax, Set the useESM property to true in the config file to enable ESM syntax.

TODO:

  • Allow user to reduce the final set of models included
    • e.g., my client only needs 4 of the 100 collections, so only include those in output
  • ID input types should be treated like strings
  • Output folder should be specified in the config file, not the second CLI param
  • Support building output as an npm package
  • Still doing a lot of .map().join('\n'), but would like to move that into the template itself
    • e.g.: {{#items}}{{.}}{{/items}} instead of items.join('\n')
  • TESTS!!