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
The output will be a folder with a bunch of models
node ^14.14.0
- "graphql-tag": "^2.12.6"
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)
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)
}
}
})
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
}
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.
By default, the exported collections use CommonJS syntax, Set the useESM
property to true
in the config file to enable ESM syntax.
- ID input types should be treated like strings
- Be able to somehow run queries that do not have arbitrary response payloads (for queries not related to a Model/Collection)
- 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 ofitems.join('\n')
- e.g.:
- TESTS!!