Skip to content

Commit

Permalink
Add a mutation to graphql
Browse files Browse the repository at this point in the history
  • Loading branch information
jarrod-lowe committed Aug 15, 2024
1 parent 59591ad commit ff71e4b
Show file tree
Hide file tree
Showing 14 changed files with 278 additions and 12 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ override.tf.json
# Ignore CLI configuration files
.terraformrc
terraform.rc

.validate
.apply
plan.tfplan

graphql/node_modules
14 changes: 11 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ RW_ROLE = arn:aws:iam::$(ACCOUNT_ID):role/GitHubAction-Wildsea-rw-dev

all: $(TERRAFOM_VALIDATE)

include graphql/graphql.mk

.PHONY: terraform-format
terraform-format: $(addprefix terraform-format-environment-,$(TERRAFORM_ENVIRONMENTS)) $(addprefix terraform-format-module-,$(TERRAFORM_MODULES))
@true
Expand All @@ -35,13 +37,16 @@ terraform/environment/aws-dev/.apply: terraform/environment/aws-dev/*.tf terrafo
./terraform/environment/aws-dev/deploy.sh $(ACCOUNT_ID) dev
touch $@

terraform/environment/wildsea-dev/plan.tfplan: terraform/environment/wildsea-dev/*.tf terraform/module/wildsea/*.tf terraform/environment/wildsea-dev/.terraform
terraform/environment/wildsea-dev/plan.tfplan: terraform/environment/wildsea-dev/*.tf terraform/module/wildsea/*.tf terraform/environment/wildsea-dev/.terraform $(GRAPHQL)
cd terraform/environment/wildsea-dev ; ../../../scripts/run-as.sh $(RO_ROLE) \
terraform plan -out=./plan.tfplan

terraform/environment/wildsea-dev/.apply: terraform/environment/wildsea-dev/plan.tfplan
terraform/environment/wildsea-dev/.apply: terraform/environment/wildsea-dev/plan.tfplan $(GRAPHQL)
cd terraform/environment/wildsea-dev ; ../../../scripts/run-as.sh $(RW_ROLE) \
terraform apply ./plan.tfplan
terraform apply ./plan.tfplan ; \
status=$$? ; \
rm -f $< ; \
[ "$$status" -eq 0 ]
touch $@

terraform/environment/wildsea-dev/.terraform: terraform/environment/wildsea-dev/*.tf terraform/module/wildsea/*.tf
Expand All @@ -54,3 +59,6 @@ terraform/environment/wildsea-dev/.terraform: terraform/environment/wildsea-dev/
clean:
rm -f terraform/environment/*/.validate
rm -f terraform/environment/*/plan.tfplan
rm -f graphql/mutation/*/appsync.js
rm -f graphql/query/*/appsync.js
rm -rf graphql/node_modules
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ If you do not set the secret, then Cognito will be used as the identity source.

## Development Environment

Install esbuild with `sudo npm install -g --save-exact --save-dev esbuild`

After having set up the AWS Account, use `AWS_PROFILE=<profile> make dev` to
deploy a development version. If this is a different AWS Account from the real
deployment, you will need to create an S3 bucket for the state, in the same way
Expand Down
20 changes: 20 additions & 0 deletions graphql/graphql.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
graphql/%/appsync.js: graphql/node_modules $(wildcard graphql/%/*.ts)
cd graphql && \
esbuild $*/*.ts \
--bundle \
--external:"@aws-appsync/utils" \
--format=esm \
--platform=node \
--target=esnext \
--sourcemap=inline \
--sources-content=false \
--outdir=$*

graphql/node_modules: graphql/package.json
cd graphql && npm install

GRAPHQL := $(patsubst %.ts,%.js,$(wildcard graphql/*/*/appsync.ts))

.PHONY: graphql
graphql: $(GRAPHQL)
echo $(GRAPHQL)
37 changes: 37 additions & 0 deletions graphql/mutation/createGame/appsync.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

63 changes: 63 additions & 0 deletions graphql/mutation/createGame/appsync.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { util, Context, DynamoDBPutItemRequest, AppSyncIdentityCognito } from '@aws-appsync/utils';

/**
* A CreateGameInput creates a Game.
* They are stored in DynamoDB with a PK of `GAME#<id>` and an SK of `GAME`.
* The ID is a UUID
* The fireflyUserId is the Cognito ID of the user
input CreateGameInput {
name: String!
description: String
}
type Game {
id: ID!
name: String!
description: String
publicNotes: String
privateNotes: String
fireflyUserId: ID!
createdAt: AWSDateTime!
updatedAt: AWSDateTime!
}
*/

interface CreateGameInput {
name: string;
description?: string;
}

export function request(ctx: Context<{ input: CreateGameInput }>): DynamoDBPutItemRequest {

Check failure on line 31 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L31

ES2015 modules are forbidden.
if (!ctx.identity) {

Check failure on line 32 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L32

Unsafe member access .identity on an `any` value.
util.error('Unauthorized: Identity information is missing.');

Check failure on line 33 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L33

Unsafe call of an `any` typed value.
}

const identity = ctx.identity as AppSyncIdentityCognito;

Check failure on line 36 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L36

Unsafe member access .identity on an `any` value.
if (!identity.sub) {
util.error('Unauthorized: User ID is missing.');
}

const { input } = ctx.arguments;

Check failure on line 41 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L41

ES2015 block-scoped variables are forbidden.

Check failure on line 41 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L41

Unsafe assignment of an `any` value.
const id = util.autoId();

Check failure on line 42 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L42

Unsafe member access .autoId on an `any` value.
const timestamp = util.time.nowISO8601();

Check failure on line 43 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L43

ES2015 block-scoped variables are forbidden.

Check failure on line 43 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L43

Unsafe call of an `any` typed value.
return {

Check failure on line 44 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L44

ES5 trailing commas in array/object literals are forbidden.
operation: 'PutItem',
key: util.dynamodb.toMapValues({ PK: `GAME#${id}`, SK: 'GAME' }),

Check failure on line 46 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L46

Unsafe assignment of an `any` value.
attributeValues: util.dynamodb.toMapValues({

Check failure on line 47 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L47

Unsafe assignment of an `any` value.
...input,
id,

Check failure on line 49 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L49

Unsafe assignment of an `any` value.
fireflyUserId: identity.sub,

Check failure on line 50 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L50

Unsafe member access .sub on an `any` value.
createdAt: timestamp,

Check failure on line 51 in graphql/mutation/createGame/appsync.ts

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/mutation/createGame/appsync.ts#L51

Unsafe assignment of an `any` value.
updatedAt: timestamp,
}),
};
}

export function response(ctx: Context): unknown {
const { error, result } = ctx;
if (error) {
return util.appendError(error.message, error.type, result);
}
return result;
}
27 changes: 27 additions & 0 deletions graphql/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions graphql/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{

Check failure on line 1 in graphql/package.json

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/package.json#L1

Filename package.json does not match the file name pattern ^([a-z][a-z0-9]*)(-[a-z0-9]+)*(.spec|.test)?.ts$
"name": "graphql",
"version": "1.0.0",
"dependencies": {
"@aws-appsync/utils": "^1.7.0"

Check failure on line 5 in graphql/package.json

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

graphql/package.json#L5

You have a misspelled word: aws on String
}
}
10 changes: 3 additions & 7 deletions graphql/schema.graphql
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
type Mutation {
createGame(input: CreateGameInput!): Game!
createGame(input: CreateGameInput!): Game! @aws_cognito_user_pools
}

type Query {
getGame(input: ID!): Game!
getGame(input: ID!): Game! @aws_cognito_user_pools
}

input CreateGameInput {
name: String!
description: String
publicNotes: String
privateNotes: String
fireflyUserId: ID!
players: [ID!]!
}

type Game {
type Game @aws_cognito_user_pools {
id: ID!
name: String!
description: String
Expand Down
38 changes: 38 additions & 0 deletions terraform/environment/wildsea-dev/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file removed terraform/environment/wildsea-dev/plan
Binary file not shown.
8 changes: 7 additions & 1 deletion terraform/module/iac-roles/policy.tf
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ data "aws_iam_policy_document" "ro" {
sid = "CognitoIdpGlobal"
actions = [
"cognito-idp:DescribeUserPoolDomain",
"appsync:SetWebACL",
"wafv2:GetWebACLForResource",
"wafv2:GetWebAcl",
"appsync:GetResolver",
]
resources = [
"*"
Expand Down Expand Up @@ -194,6 +194,9 @@ data "aws_iam_policy_document" "rw" {
"cognito-identity:SetIdentityPoolRoles",
"cognito-identity:TagResource",
"cognito-identity:UntagResource",
"appsync:CreateResolver",
"appsync:DeleteResolver",
"appsync:SetWebACL",
]
resources = [
"*"
Expand Down Expand Up @@ -389,6 +392,9 @@ data "aws_iam_policy_document" "rw_boundary" {
"appsync:SetWebACL",
"wafv2:GetWebACLForResource",
"wafv2:GetWebAcl",
"appsync:CreateResolver",
"appsync:DeleteResolver",
"appsync:GetResolver",
]
resources = [
"*"
Expand Down
2 changes: 1 addition & 1 deletion terraform/module/wildsea/cognito.tf
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ resource "aws_cognito_identity_provider" "idp" {
resource "aws_cognito_user_pool_client" "cognito" {
name = var.prefix
user_pool_id = aws_cognito_user_pool.cognito.id
generate_secret = true
generate_secret = false
explicit_auth_flows = ["ALLOW_REFRESH_TOKEN_AUTH", "ALLOW_USER_PASSWORD_AUTH", "ALLOW_USER_SRP_AUTH"]
allowed_oauth_flows_user_pool_client = true
callback_urls = ["https://TODO"]
Expand Down
59 changes: 59 additions & 0 deletions terraform/module/wildsea/graphql.tf
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,62 @@ resource "aws_iam_role_policy_attachment" "graphql_datasource" {
role = aws_iam_role.graphql_datasource.name
policy_arn = aws_iam_policy.graphql_datasource.arn
}

locals {
mutations = distinct([for d in fileset("${path.module}/../../../graphql/mutation", "**") : dirname(d)])
queries = distinct([for d in fileset("${path.module}/../../../graphql/query", "**") : dirname(d)])

mutations_map = {
for mutation in local.mutations : replace(mutation, "../../../graphql/mutation/", "") => {
"type" : "Mutation",
"path" : "../../../graphql/mutation/${mutation}/appsync.js",
"make" : "graphql/mutation/${mutation}/appsync.js",
"source" : "../../../graphql/mutation/${mutation}/appsync.ts"
}
}

queries_map = {
for query in local.queries : replace(query, "../../../graphql/query/", "") => {
"type" : "Query",
"path" : "../../../graphql/query/${query}/appsync.js",
"make" : "graphql/query/${query}/appsync.js",
"source" : "../../../graphql/query/${query}/appsync.ts"
}
}

all = merge(local.mutations_map, local.queries_map)
}

resource "aws_appsync_resolver" "resolver" {
for_each = local.all

api_id = aws_appsync_graphql_api.graphql.id
type = each.value.type
field = each.key
data_source = aws_appsync_datasource.graphql.name
code = data.local_file.graphql_code[each.key].content

runtime {
name = "APPSYNC_JS"
runtime_version = "1.0.0"
}
}

resource "null_resource" "graphql_compile" {
for_each = local.all

provisioner "local-exec" {
command = "cd ${path.module}/../../.. && make ${each.value.make}"
}

triggers = {
source_change = filesha256(each.value.source)
dest_file = each.value.path
}
}

data "local_file" "graphql_code" {
for_each = local.all

filename = null_resource.graphql_compile[each.key].triggers.dest_file
}

0 comments on commit ff71e4b

Please sign in to comment.