├── .gitignore
├── .graphqlconfig.yml
├── .vscode
└── settings.json
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── amplify.yml
├── amplify.yml.old
├── amplify
├── .config
│ └── project-config.json
├── README.md
├── backend
│ ├── api
│ │ └── AlexaBackend
│ │ │ ├── parameters.json
│ │ │ ├── schema.graphql
│ │ │ ├── stacks
│ │ │ └── CustomResources.json
│ │ │ └── transform.conf.json
│ ├── auth
│ │ └── awsalexaui51864c6a
│ │ │ ├── awsalexaui51864c6a-cloudformation-template.yml
│ │ │ └── parameters.json
│ └── backend-config.json
├── cli.json
└── hooks
│ ├── README.md
│ ├── post-push.sh.sample
│ └── pre-push.js.sample
├── app
├── .gitignore
├── README.md
├── public
│ ├── favicon.ico
│ ├── index.html
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── robots.txt
└── src
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── reportWebVitals.js
│ └── setupTests.js
├── aws_alexa.png
├── package.json
├── package.json.old
├── public
├── favicon.ico
├── index.html
├── manifest.json
└── static
│ └── images
│ └── lamp.png
├── src
├── App.css
├── App.js
├── App.test.js
├── Device.js
├── graphql
│ ├── mutations.js
│ ├── queries.js
│ ├── schema.json
│ └── subscriptions.js
├── index.css
├── index.js
├── logo.svg
└── serviceWorker.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # Jetbrains
4 | .idea
5 |
6 | # dependencies
7 | /node_modules
8 | /.pnp
9 | .pnp.js
10 |
11 | # testing
12 | /coverage
13 |
14 | # production
15 | /build
16 |
17 | # misc
18 | .DS_Store
19 | .env.local
20 | .env.development.local
21 | .env.test.local
22 | .env.production.local
23 |
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # for public project
29 | amplify/team-provider-info.json
30 |
31 | #amplify
32 | amplify/\#current-cloud-backend
33 | amplify/.config/local-*
34 | amplify/logs
35 | amplify/mock-data
36 | amplify/backend/amplify-meta.json
37 | amplify/backend/awscloudformation
38 | amplify/backend/.temp
39 | build/
40 | dist/
41 | node_modules/
42 | aws-exports.js
43 | awsconfiguration.json
44 | amplifyconfiguration.json
45 | amplify-build-config.json
46 | amplify-gradle-config.json
47 | amplifytools.xcconfig
48 | .secret-*
--------------------------------------------------------------------------------
/.graphqlconfig.yml:
--------------------------------------------------------------------------------
1 | projects:
2 | AlexaBackend:
3 | schemaPath: src/graphql/schema.json
4 | includes:
5 | - src/graphql/**/*.js
6 | excludes:
7 | - ./amplify/**
8 | extensions:
9 | amplify:
10 | codeGenTarget: javascript
11 | generatedFileName: ''
12 | docsFilePath: src/graphql
13 | extensions:
14 | amplify:
15 | version: 3
16 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "amplify/.config": true,
4 | "amplify/**/*-parameters.json": true,
5 | "amplify/**/amplify.state": true,
6 | "amplify/**/transform.conf.json": true,
7 | "amplify/#current-cloud-backend": true,
8 | "amplify/backend/amplify-meta.json": true,
9 | "amplify/backend/awscloudformation": true
10 | }
11 | }
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | ## Code of Conduct
2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
4 | opensource-codeofconduct@amazon.com with any additional questions or comments.
5 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
4 | documentation, we greatly value feedback and contributions from our community.
5 |
6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
7 | information to effectively respond to your bug report or contribution.
8 |
9 |
10 | ## Reporting Bugs/Feature Requests
11 |
12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features.
13 |
14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already
15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
16 |
17 | * A reproducible test case or series of steps
18 | * The version of our code being used
19 | * Any modifications you've made relevant to the bug
20 | * Anything unusual about your environment or deployment
21 |
22 |
23 | ## Contributing via Pull Requests
24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
25 |
26 | 1. You are working against the latest source on the *master* branch.
27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
29 |
30 | To send us a pull request, please:
31 |
32 | 1. Fork the repository.
33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
34 | 3. Ensure local tests pass.
35 | 4. Commit to your fork using clear commit messages.
36 | 5. Send us a pull request, answering any default questions in the pull request interface.
37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
38 |
39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
41 |
42 |
43 | ## Finding contributions to work on
44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start.
45 |
46 |
47 | ## Code of Conduct
48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
50 | opensource-codeofconduct@amazon.com with any additional questions or comments.
51 |
52 |
53 | ## Security issue notifications
54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
55 |
56 |
57 | ## Licensing
58 |
59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
60 |
61 | We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes.
62 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software is furnished to do so.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15 |
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Alexa Workshop Smart Home - Device Binding UI
2 |
3 | This is the source code of [Step 1: Build Device Binding UI](https://alexaworkshop.com/smart-home/1.build-device-ui/).
4 | If you are looking for the lab content, please visit the above link.
5 |
6 | If you are looking for the whole lab, please visit [AWS & Alexa Workshop - Smart Home Skills](https://alexaworkshop.com/smart-home/).
7 |
8 | If you have any issues, please create issues in [aws-samples/aws-alexa-workshop](https://github.com/aws-samples/aws-alexa-workshop/issues) repository.
9 |
10 | 
11 |
12 | ## License
13 |
14 | This library is licensed under the MIT-0 License. See the LICENSE file.
15 |
16 |
--------------------------------------------------------------------------------
/amplify.yml:
--------------------------------------------------------------------------------
1 | version: 0.1
2 | backend:
3 | phases:
4 | build:
5 | commands:
6 | - '# Execute Amplify CLI with the helper script'
7 | - amplifyPush --simple
8 | frontend:
9 | phases:
10 | preBuild:
11 | commands:
12 | - yarn install
13 | build:
14 | commands:
15 | - yarn run build
16 | artifacts:
17 | baseDirectory: build
18 | files:
19 | - '**/*'
20 | cache:
21 | paths:
22 | - node_modules/**/*
23 |
--------------------------------------------------------------------------------
/amplify.yml.old:
--------------------------------------------------------------------------------
1 | version: 0.1
2 | backend:
3 | phases:
4 | build:
5 | commands:
6 | - '# Execute Amplify CLI with the helper script'
7 | - amplifyPush --simple
8 | frontend:
9 | phases:
10 | preBuild:
11 | commands:
12 | - yarn install
13 | build:
14 | commands:
15 | - yarn run build
16 | artifacts:
17 | baseDirectory: build
18 | files:
19 | - '**/*'
20 | cache:
21 | paths:
22 | - node_modules/**/*
23 |
--------------------------------------------------------------------------------
/amplify/.config/project-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "aws-alexa-ui",
3 | "version": "3.0",
4 | "frontend": "javascript",
5 | "javascript": {
6 | "framework": "react",
7 | "config": {
8 | "SourceDir": "src",
9 | "DistributionDir": "build",
10 | "BuildCommand": "npm run-script build",
11 | "StartCommand": "npm run-script start"
12 | }
13 | },
14 | "providers": [
15 | "awscloudformation"
16 | ]
17 | }
--------------------------------------------------------------------------------
/amplify/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Amplify CLI
2 | This directory was generated by [Amplify CLI](https://docs.amplify.aws/cli).
3 |
4 | Helpful resources:
5 | - Amplify documentation: https://docs.amplify.aws
6 | - Amplify CLI documentation: https://docs.amplify.aws/cli
7 | - More details on this folder & generated files: https://docs.amplify.aws/cli/reference/files
8 | - Join Amplify's community: https://amplify.aws/community/
9 |
--------------------------------------------------------------------------------
/amplify/backend/api/AlexaBackend/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "AppSyncApiName": "AlexaBackend",
3 | "DynamoDBBillingMode": "PAY_PER_REQUEST",
4 | "DynamoDBEnableServerSideEncryption": "false",
5 | "AuthCognitoUserPoolId": {
6 | "Fn::GetAtt": [
7 | "authawsalexaui51864c6a",
8 | "Outputs.UserPoolId"
9 | ]
10 | }
11 | }
--------------------------------------------------------------------------------
/amplify/backend/api/AlexaBackend/schema.graphql:
--------------------------------------------------------------------------------
1 | type Device @model
2 | @key(fields: ["thingName"])
3 | @key(name: "ByUsernameThingName", fields: ["username", "thingName"])
4 | {
5 | thingName: String!
6 | username: String!
7 | description: String
8 | }
--------------------------------------------------------------------------------
/amplify/backend/api/AlexaBackend/stacks/CustomResources.json:
--------------------------------------------------------------------------------
1 | {
2 | "AWSTemplateFormatVersion": "2010-09-09",
3 | "Description": "An auto-generated nested stack.",
4 | "Metadata": {},
5 | "Parameters": {
6 | "AppSyncApiId": {
7 | "Type": "String",
8 | "Description": "The id of the AppSync API associated with this project."
9 | },
10 | "AppSyncApiName": {
11 | "Type": "String",
12 | "Description": "The name of the AppSync API",
13 | "Default": "AppSyncSimpleTransform"
14 | },
15 | "env": {
16 | "Type": "String",
17 | "Description": "The environment name. e.g. Dev, Test, or Production",
18 | "Default": "NONE"
19 | },
20 | "S3DeploymentBucket": {
21 | "Type": "String",
22 | "Description": "The S3 bucket containing all deployment assets for the project."
23 | },
24 | "S3DeploymentRootKey": {
25 | "Type": "String",
26 | "Description": "An S3 key relative to the S3DeploymentBucket that points to the root\nof the deployment directory."
27 | }
28 | },
29 | "Resources": {
30 | "EmptyResource": {
31 | "Type": "Custom::EmptyResource",
32 | "Condition": "AlwaysFalse"
33 | }
34 | },
35 | "Conditions": {
36 | "HasEnvironmentParameter": {
37 | "Fn::Not": [
38 | {
39 | "Fn::Equals": [
40 | {
41 | "Ref": "env"
42 | },
43 | "NONE"
44 | ]
45 | }
46 | ]
47 | },
48 | "AlwaysFalse": {
49 | "Fn::Equals": [
50 | "true",
51 | "false"
52 | ]
53 | }
54 | },
55 | "Outputs": {
56 | "EmptyOutput": {
57 | "Description": "An empty output. You may delete this if you have at least one resource above.",
58 | "Value": ""
59 | }
60 | }
61 | }
--------------------------------------------------------------------------------
/amplify/backend/api/AlexaBackend/transform.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 5,
3 | "ElasticsearchWarning": true
4 | }
--------------------------------------------------------------------------------
/amplify/backend/auth/awsalexaui51864c6a/awsalexaui51864c6a-cloudformation-template.yml:
--------------------------------------------------------------------------------
1 | AWSTemplateFormatVersion: 2010-09-09
2 |
3 | Parameters:
4 | env:
5 | Type: String
6 | authRoleName:
7 | Type: String
8 | unauthRoleName:
9 | Type: String
10 | authRoleArn:
11 | Type: String
12 | unauthRoleArn:
13 | Type: String
14 |
15 |
16 |
17 |
18 | identityPoolName:
19 | Type: String
20 |
21 | allowUnauthenticatedIdentities:
22 | Type: String
23 |
24 | openIdLambdaRoleName:
25 | Type: String
26 |
27 | resourceNameTruncated:
28 | Type: String
29 |
30 | userPoolName:
31 | Type: String
32 |
33 | autoVerifiedAttributes:
34 | Type: CommaDelimitedList
35 |
36 | mfaConfiguration:
37 | Type: String
38 |
39 | mfaTypes:
40 | Type: CommaDelimitedList
41 |
42 | smsAuthenticationMessage:
43 | Type: String
44 |
45 | smsVerificationMessage:
46 | Type: String
47 |
48 | emailVerificationSubject:
49 | Type: String
50 |
51 | emailVerificationMessage:
52 | Type: String
53 |
54 | defaultPasswordPolicy:
55 | Type: String
56 |
57 | passwordPolicyMinLength:
58 | Type: Number
59 |
60 | passwordPolicyCharacters:
61 | Type: CommaDelimitedList
62 |
63 | requiredAttributes:
64 | Type: CommaDelimitedList
65 |
66 | userpoolClientName:
67 | Type: String
68 |
69 | userpoolClientGenerateSecret:
70 | Type: String
71 |
72 | userpoolClientRefreshTokenValidity:
73 | Type: Number
74 |
75 | userpoolClientWriteAttributes:
76 | Type: CommaDelimitedList
77 |
78 | userpoolClientReadAttributes:
79 | Type: CommaDelimitedList
80 |
81 | mfaLambdaRole:
82 | Type: String
83 |
84 | userpoolClientLambdaRole:
85 | Type: String
86 |
87 | userpoolClientSetAttributes:
88 | Type: String
89 |
90 | resourceName:
91 | Type: String
92 |
93 | authSelections:
94 | Type: String
95 |
96 | useDefault:
97 | Type: String
98 |
99 | usernameAttributes:
100 | Type: CommaDelimitedList
101 |
102 | additionalQuestions:
103 | Type: CommaDelimitedList
104 |
105 | dependsOn:
106 | Type: CommaDelimitedList
107 |
108 | Conditions:
109 | ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ]
110 |
111 | Resources:
112 |
113 |
114 | # BEGIN SNS ROLE RESOURCE
115 | SNSRole:
116 | # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process
117 | Type: AWS::IAM::Role
118 | Properties:
119 | RoleName: !If [ShouldNotCreateEnvResources, 'awsale51864c6a_sns-role', !Join ['',['awsale51864c6a_sns-role', '-', !Ref env]]]
120 | AssumeRolePolicyDocument:
121 | Version: "2012-10-17"
122 | Statement:
123 | - Sid: ""
124 | Effect: "Allow"
125 | Principal:
126 | Service: "cognito-idp.amazonaws.com"
127 | Action:
128 | - "sts:AssumeRole"
129 | Condition:
130 | StringEquals:
131 | sts:ExternalId: awsale51864c6a_role_external_id
132 | Policies:
133 | -
134 | PolicyName: awsale51864c6a-sns-policy
135 | PolicyDocument:
136 | Version: "2012-10-17"
137 | Statement:
138 | -
139 | Effect: "Allow"
140 | Action:
141 | - "sns:Publish"
142 | Resource: "*"
143 | # BEGIN USER POOL RESOURCES
144 | UserPool:
145 | # Created upon user selection
146 | # Depends on SNS Role for Arn if MFA is enabled
147 | Type: AWS::Cognito::UserPool
148 | UpdateReplacePolicy: Retain
149 | Properties:
150 | UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]]
151 |
152 | Schema:
153 |
154 | -
155 | Name: email
156 | Required: true
157 | Mutable: true
158 |
159 |
160 |
161 |
162 | AutoVerifiedAttributes: !Ref autoVerifiedAttributes
163 |
164 |
165 | EmailVerificationMessage: !Ref emailVerificationMessage
166 | EmailVerificationSubject: !Ref emailVerificationSubject
167 |
168 | Policies:
169 | PasswordPolicy:
170 | MinimumLength: !Ref passwordPolicyMinLength
171 | RequireLowercase: false
172 | RequireNumbers: false
173 | RequireSymbols: false
174 | RequireUppercase: false
175 |
176 | UsernameAttributes: !Ref usernameAttributes
177 |
178 | MfaConfiguration: !Ref mfaConfiguration
179 | SmsVerificationMessage: !Ref smsVerificationMessage
180 | SmsConfiguration:
181 | SnsCallerArn: !GetAtt SNSRole.Arn
182 | ExternalId: awsale51864c6a_role_external_id
183 |
184 |
185 | UserPoolClientWeb:
186 | # Created provide application access to user pool
187 | # Depends on UserPool for ID reference
188 | Type: "AWS::Cognito::UserPoolClient"
189 | Properties:
190 | ClientName: awsale51864c6a_app_clientWeb
191 |
192 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
193 | UserPoolId: !Ref UserPool
194 | DependsOn: UserPool
195 | UserPoolClient:
196 | # Created provide application access to user pool
197 | # Depends on UserPool for ID reference
198 | Type: "AWS::Cognito::UserPoolClient"
199 | Properties:
200 | ClientName: !Ref userpoolClientName
201 |
202 | GenerateSecret: !Ref userpoolClientGenerateSecret
203 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
204 | UserPoolId: !Ref UserPool
205 | DependsOn: UserPool
206 | # BEGIN USER POOL LAMBDA RESOURCES
207 | UserPoolClientRole:
208 | # Created to execute Lambda which gets userpool app client config values
209 | Type: 'AWS::IAM::Role'
210 | Properties:
211 | RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',[!Ref userpoolClientLambdaRole, '-', !Ref env]]]
212 | AssumeRolePolicyDocument:
213 | Version: '2012-10-17'
214 | Statement:
215 | - Effect: Allow
216 | Principal:
217 | Service:
218 | - lambda.amazonaws.com
219 | Action:
220 | - 'sts:AssumeRole'
221 | DependsOn: UserPoolClient
222 | UserPoolClientLambda:
223 | # Lambda which gets userpool app client config values
224 | # Depends on UserPool for id
225 | # Depends on UserPoolClientRole for role ARN
226 | Type: 'AWS::Lambda::Function'
227 | Properties:
228 | Code:
229 | ZipFile: !Join
230 | - |+
231 | - - 'const response = require(''cfn-response'');'
232 | - 'const aws = require(''aws-sdk'');'
233 | - 'const identity = new aws.CognitoIdentityServiceProvider();'
234 | - 'exports.handler = (event, context, callback) => {'
235 | - ' if (event.RequestType == ''Delete'') { '
236 | - ' response.send(event, context, response.SUCCESS, {})'
237 | - ' }'
238 | - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {'
239 | - ' const params = {'
240 | - ' ClientId: event.ResourceProperties.clientId,'
241 | - ' UserPoolId: event.ResourceProperties.userpoolId'
242 | - ' };'
243 | - ' identity.describeUserPoolClient(params).promise()'
244 | - ' .then((res) => {'
245 | - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});'
246 | - ' })'
247 | - ' .catch((err) => {'
248 | - ' response.send(event, context, response.FAILED, {err});'
249 | - ' });'
250 | - ' }'
251 | - '};'
252 | Handler: index.handler
253 | Runtime: nodejs14.x
254 | Timeout: '300'
255 | Role: !GetAtt
256 | - UserPoolClientRole
257 | - Arn
258 | DependsOn: UserPoolClientRole
259 | UserPoolClientLambdaPolicy:
260 | # Sets userpool policy for the role that executes the Userpool Client Lambda
261 | # Depends on UserPool for Arn
262 | # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing
263 | Type: 'AWS::IAM::Policy'
264 | Properties:
265 | PolicyName: awsale51864c6a_userpoolclient_lambda_iam_policy
266 | Roles:
267 | - !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',[!Ref userpoolClientLambdaRole, '-', !Ref env]]]
268 | PolicyDocument:
269 | Version: '2012-10-17'
270 | Statement:
271 | - Effect: Allow
272 | Action:
273 | - 'cognito-idp:DescribeUserPoolClient'
274 | Resource: !GetAtt UserPool.Arn
275 | DependsOn: UserPoolClientLambda
276 | UserPoolClientLogPolicy:
277 | # Sets log policy for the role that executes the Userpool Client Lambda
278 | # Depends on UserPool for Arn
279 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
280 | Type: 'AWS::IAM::Policy'
281 | Properties:
282 | PolicyName: awsale51864c6a_userpoolclient_lambda_log_policy
283 | Roles:
284 | - !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',[!Ref userpoolClientLambdaRole, '-', !Ref env]]]
285 | PolicyDocument:
286 | Version: 2012-10-17
287 | Statement:
288 | - Effect: Allow
289 | Action:
290 | - 'logs:CreateLogGroup'
291 | - 'logs:CreateLogStream'
292 | - 'logs:PutLogEvents'
293 | Resource: !Sub
294 | - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*
295 | - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda}
296 | DependsOn: UserPoolClientLambdaPolicy
297 | UserPoolClientInputs:
298 | # Values passed to Userpool client Lambda
299 | # Depends on UserPool for Id
300 | # Depends on UserPoolClient for Id
301 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
302 | Type: 'Custom::LambdaCallout'
303 | Properties:
304 | ServiceToken: !GetAtt UserPoolClientLambda.Arn
305 | clientId: !Ref UserPoolClient
306 | userpoolId: !Ref UserPool
307 | DependsOn: UserPoolClientLogPolicy
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 | # BEGIN IDENTITY POOL RESOURCES
316 |
317 |
318 | IdentityPool:
319 | # Always created
320 | Type: AWS::Cognito::IdentityPool
321 | Properties:
322 | IdentityPoolName: !If [ShouldNotCreateEnvResources, 'awsalexaui51864c6a_identitypool_51864c6a', !Join ['',['awsalexaui51864c6a_identitypool_51864c6a', '__', !Ref env]]]
323 |
324 | CognitoIdentityProviders:
325 | - ClientId: !Ref UserPoolClient
326 | ProviderName: !Sub
327 | - cognito-idp.${region}.amazonaws.com/${client}
328 | - { region: !Ref "AWS::Region", client: !Ref UserPool}
329 | - ClientId: !Ref UserPoolClientWeb
330 | ProviderName: !Sub
331 | - cognito-idp.${region}.amazonaws.com/${client}
332 | - { region: !Ref "AWS::Region", client: !Ref UserPool}
333 |
334 | AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities
335 |
336 |
337 | DependsOn: UserPoolClientInputs
338 |
339 |
340 | IdentityPoolRoleMap:
341 | # Created to map Auth and Unauth roles to the identity pool
342 | # Depends on Identity Pool for ID ref
343 | Type: AWS::Cognito::IdentityPoolRoleAttachment
344 | Properties:
345 | IdentityPoolId: !Ref IdentityPool
346 | Roles:
347 | unauthenticated: !Ref unauthRoleArn
348 | authenticated: !Ref authRoleArn
349 | DependsOn: IdentityPool
350 |
351 |
352 | Outputs :
353 |
354 | IdentityPoolId:
355 | Value: !Ref 'IdentityPool'
356 | Description: Id for the identity pool
357 | IdentityPoolName:
358 | Value: !GetAtt IdentityPool.Name
359 |
360 |
361 |
362 |
363 | UserPoolId:
364 | Value: !Ref 'UserPool'
365 | Description: Id for the user pool
366 | UserPoolName:
367 | Value: !Ref userPoolName
368 | AppClientIDWeb:
369 | Value: !Ref 'UserPoolClientWeb'
370 | Description: The user pool app client id for web
371 | AppClientID:
372 | Value: !Ref 'UserPoolClient'
373 | Description: The user pool app client id
374 | AppClientSecret:
375 | Value: !GetAtt UserPoolClientInputs.appSecret
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
--------------------------------------------------------------------------------
/amplify/backend/auth/awsalexaui51864c6a/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "identityPoolName": "awsalexaui51864c6a_identitypool_51864c6a",
3 | "allowUnauthenticatedIdentities": false,
4 | "openIdLambdaRoleName": "awsale51864c6a_openid_lambda_role",
5 | "resourceNameTruncated": "awsale51864c6a",
6 | "userPoolName": "awsalexaui51864c6a_userpool_51864c6a",
7 | "autoVerifiedAttributes": [
8 | "email"
9 | ],
10 | "mfaConfiguration": "OFF",
11 | "mfaTypes": [
12 | "SMS Text Message"
13 | ],
14 | "smsAuthenticationMessage": "Your authentication code is {####}",
15 | "smsVerificationMessage": "Your verification code is {####}",
16 | "emailVerificationSubject": "Your verification code",
17 | "emailVerificationMessage": "Your verification code is {####}",
18 | "defaultPasswordPolicy": false,
19 | "passwordPolicyMinLength": 8,
20 | "passwordPolicyCharacters": [],
21 | "requiredAttributes": [
22 | "email"
23 | ],
24 | "userpoolClientName": "awsale51864c6a_app_client",
25 | "userpoolClientGenerateSecret": true,
26 | "userpoolClientRefreshTokenValidity": 30,
27 | "userpoolClientWriteAttributes": [
28 | "email"
29 | ],
30 | "userpoolClientReadAttributes": [
31 | "email"
32 | ],
33 | "mfaLambdaRole": "awsale51864c6a_totp_lambda_role",
34 | "userpoolClientLambdaRole": "awsale51864c6a_userpoolclient_lambda_role",
35 | "userpoolClientSetAttributes": false,
36 | "resourceName": "awsalexaui51864c6a",
37 | "authSelections": "identityPoolAndUserPool",
38 | "authRoleName": {
39 | "Ref": "AuthRoleName"
40 | },
41 | "unauthRoleName": {
42 | "Ref": "UnauthRoleName"
43 | },
44 | "authRoleArn": {
45 | "Fn::GetAtt": [
46 | "AuthRole",
47 | "Arn"
48 | ]
49 | },
50 | "unauthRoleArn": {
51 | "Fn::GetAtt": [
52 | "UnauthRole",
53 | "Arn"
54 | ]
55 | },
56 | "useDefault": "default",
57 | "usernameAttributes": [
58 | "email, phone_number"
59 | ],
60 | "additionalQuestions": [],
61 | "dependsOn": []
62 | }
--------------------------------------------------------------------------------
/amplify/backend/backend-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "auth": {
3 | "awsalexaui51864c6a": {
4 | "service": "Cognito",
5 | "providerPlugin": "awscloudformation",
6 | "dependsOn": []
7 | }
8 | },
9 | "api": {
10 | "AlexaBackend": {
11 | "service": "AppSync",
12 | "providerPlugin": "awscloudformation",
13 | "output": {
14 | "securityType": "AMAZON_COGNITO_USER_POOLS"
15 | }
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/amplify/cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "features": {
3 | "graphqltransformer": {
4 | "addmissingownerfields": true,
5 | "validatetypenamereservedwords": true,
6 | "useexperimentalpipelinedtransformer": false,
7 | "enableiterativegsiupdates": false,
8 | "secondarykeyasgsi": true
9 | },
10 | "frontend-ios": {
11 | "enablexcodeintegration": true
12 | },
13 | "auth": {
14 | "enablecaseinsensitivity": true
15 | },
16 | "codegen": {
17 | "useappsyncmodelgenplugin": true,
18 | "usedocsgeneratorplugin": true,
19 | "usetypesgeneratorplugin": true
20 | },
21 | "appsync": {
22 | "generategraphqlpermissions": true
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/amplify/hooks/README.md:
--------------------------------------------------------------------------------
1 | # Command Hooks
2 |
3 | Command hooks can be used to run custom scripts upon Amplify CLI lifecycle events like pre-push, post-add-function, etc.
4 |
5 | To get started, add your script files based on the expected naming convention in this directory.
6 |
7 | Learn more about the script file naming convention, hook parameters, third party dependencies, and advanced configurations at https://docs.amplify.aws/cli/usage/command-hooks
8 |
--------------------------------------------------------------------------------
/amplify/hooks/post-push.sh.sample:
--------------------------------------------------------------------------------
1 | # This is a sample hook script created by Amplify CLI.
2 | # To start using this post-push hook please change the filename:
3 | # post-push.sh.sample -> post-push.sh
4 | #
5 | # learn more: https://docs.amplify.aws/cli/usage/command-hooks
6 |
7 | if [ -z "$(which jq)" ]; then
8 | echo "Please install jq to run the sample script."
9 | exit 0
10 | fi
11 |
12 | parameters=`cat`
13 | error=$(jq -r '.error // empty' <<< "$parameters")
14 | data=$(jq -r '.data' <<< "$parameters")
15 |
16 | #
17 | # Write code here:
18 | #
19 | if [ ! -z "$error" ]; then
20 | echo "Amplify CLI emitted an error:" $(jq -r '.message' <<< "$error")
21 | exit 0
22 | fi
23 | echo "project root path:" $(pwd);
24 | echo "Amplify CLI command:" $(jq -r '.amplify | .command' <<< "$data")
--------------------------------------------------------------------------------
/amplify/hooks/pre-push.js.sample:
--------------------------------------------------------------------------------
1 | /**
2 | * This is a sample hook script created by Amplify CLI.
3 | * To start using this pre-push hook please change the filename:
4 | * pre-push.js.sample -> pre-push.js
5 | *
6 | * learn more: https://docs.amplify.aws/cli/usage/command-hooks
7 | */
8 |
9 | /**
10 | * @param data { { amplify: { environment: string, command: string, subCommand: string, argv: string[] } } }
11 | * @param error { { message: string, stack: string } }
12 | */
13 | const hookHandler = async (data, error) => {
14 | // TODO write your hook handler here
15 | };
16 |
17 | const getParameters = async () => {
18 | const fs = require("fs");
19 | return JSON.parse(fs.readFileSync(0, { encoding: "utf8" }));
20 | };
21 |
22 | getParameters()
23 | .then((event) => hookHandler(event.data, event.error))
24 | .catch((err) => {
25 | console.error(err);
26 | process.exitCode = 1;
27 | });
28 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/app/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `yarn start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
13 |
14 | The page will reload if you make edits.\
15 | You will also see any lint errors in the console.
16 |
17 | ### `yarn test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `yarn build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `yarn eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!**
35 |
36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
39 |
40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `yarn build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/app/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-alexa-workshop-smarthome-ui/b2c6425a1ae198aa1f5149269ada757bd77b6664/app/public/favicon.ico
--------------------------------------------------------------------------------
/app/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-alexa-workshop-smarthome-ui/b2c6425a1ae198aa1f5149269ada757bd77b6664/app/public/logo192.png
--------------------------------------------------------------------------------
/app/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-alexa-workshop-smarthome-ui/b2c6425a1ae198aa1f5149269ada757bd77b6664/app/public/logo512.png
--------------------------------------------------------------------------------
/app/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/app/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/app/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/app/src/App.js:
--------------------------------------------------------------------------------
1 | import logo from './logo.svg';
2 | import './App.css';
3 |
4 | function App() {
5 | return (
6 |
22 | );
23 | }
24 |
25 | export default App;
26 |
--------------------------------------------------------------------------------
/app/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render();
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/app/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById('root')
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/app/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/app/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/aws_alexa.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-alexa-workshop-smarthome-ui/b2c6425a1ae198aa1f5149269ada757bd77b6664/aws_alexa.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "aws-amplify-react": "^4.2.29",
7 | "@material-ui/core": "^4.11.3",
8 | "@material-ui/icons": "^4.11.2",
9 | "aws-amplify": "^3.3.25",
10 | "react": "^17.0.1",
11 | "react-dom": "^17.0.1",
12 | "web-vitals": "^1.0.1"
13 | },
14 | "devDependencies": {
15 | "react-scripts": "5.0.0",
16 | "@testing-library/jest-dom": "^5.11.4",
17 | "@testing-library/react": "^11.1.0",
18 | "@testing-library/user-event": "^12.1.10"
19 | },
20 | "scripts": {
21 | "start": "react-scripts start",
22 | "build": "react-scripts build",
23 | "test": "react-scripts test",
24 | "eject": "react-scripts eject"
25 | },
26 | "eslintConfig": {
27 | "extends": [
28 | "react-app",
29 | "react-app/jest"
30 | ]
31 | },
32 | "browserslist": {
33 | "production": [
34 | ">0.2%",
35 | "not dead",
36 | "not op_mini all"
37 | ],
38 | "development": [
39 | "last 1 chrome version",
40 | "last 1 firefox version",
41 | "last 1 safari version"
42 | ]
43 | },
44 | "resolutions": {
45 | "**/**/immer": "^9.0.6",
46 | "**/**/axios": "^0.21.2",
47 | "**/**/node-fetch": "^2.6.7",
48 | "**/**/ansi-regex": "^5.0.1",
49 | "**/**/browserslist": "^4.16.5",
50 | "react-scripts/**/follow-redirects": "^1.14.7",
51 | "**/**/nth-check": "^2.0.1",
52 | "**/**/async": "^2.6.4"
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/package.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "name": "app",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "aws-amplify-react": "^4.2.29",
7 | "@material-ui/core": "^4.11.3",
8 | "@material-ui/icons": "^4.11.2",
9 | "@testing-library/jest-dom": "^5.11.4",
10 | "@testing-library/react": "^11.1.0",
11 | "@testing-library/user-event": "^12.1.10",
12 | "aws-amplify": "^3.3.25",
13 | "react": "^17.0.1",
14 | "react-dom": "^17.0.1",
15 | "react-scripts": "4.0.3",
16 | "web-vitals": "^1.0.1"
17 | },
18 | "scripts": {
19 | "start": "react-scripts start",
20 | "build": "react-scripts build",
21 | "test": "react-scripts test",
22 | "eject": "react-scripts eject"
23 | },
24 | "eslintConfig": {
25 | "extends": [
26 | "react-app",
27 | "react-app/jest"
28 | ]
29 | },
30 | "browserslist": {
31 | "production": [
32 | ">0.2%",
33 | "not dead",
34 | "not op_mini all"
35 | ],
36 | "development": [
37 | "last 1 chrome version",
38 | "last 1 firefox version",
39 | "last 1 safari version"
40 | ]
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-alexa-workshop-smarthome-ui/b2c6425a1ae198aa1f5149269ada757bd77b6664/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
22 | Alexa Workshop
23 |
24 |
25 |
26 |
27 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": ".",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/public/static/images/lamp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-alexa-workshop-smarthome-ui/b2c6425a1ae198aa1f5149269ada757bd77b6664/public/static/images/lamp.png
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | animation: App-logo-spin infinite 20s linear;
7 | height: 40vmin;
8 | pointer-events: none;
9 | }
10 |
11 | .App-header {
12 | background-color: #282c34;
13 | min-height: 100vh;
14 | display: flex;
15 | flex-direction: column;
16 | align-items: center;
17 | justify-content: center;
18 | font-size: calc(10px + 2vmin);
19 | color: white;
20 | }
21 |
22 | .App-link {
23 | color: #61dafb;
24 | }
25 |
26 | @keyframes App-logo-spin {
27 | from {
28 | transform: rotate(0deg);
29 | }
30 | to {
31 | transform: rotate(360deg);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { makeStyles } from '@material-ui/core/styles';
3 | import AppBar from '@material-ui/core/AppBar';
4 | import Toolbar from '@material-ui/core/Toolbar';
5 | import Typography from '@material-ui/core/Typography';
6 | import Button from '@material-ui/core/Button';
7 | import IconButton from '@material-ui/core/IconButton';
8 | import MenuIcon from '@material-ui/icons/Menu';
9 |
10 | import Amplify, { Auth } from 'aws-amplify';
11 | import awsconfig from './aws-exports';
12 | import { withAuthenticator } from 'aws-amplify-react'
13 |
14 | import Device from './Device';
15 |
16 | Amplify.configure(awsconfig);
17 |
18 | const useStyles = makeStyles(theme => ({
19 | root: {
20 | flexGrow: 1,
21 | },
22 | menuButton: {
23 | marginRight: theme.spacing(2),
24 | },
25 | title: {
26 | flexGrow: 1,
27 | },
28 | }));
29 |
30 | function App() {
31 | const classes = useStyles();
32 |
33 | const logout = async () => {
34 | await Auth.signOut();
35 | };
36 |
37 | return (
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | Alexa Workshop
46 |
47 |
48 |
49 |
50 |
51 |
52 | );
53 | }
54 |
55 | const signUpConfig = {
56 | defaultCountryCode: "86",
57 | usernameAttributes: "email"
58 | };
59 |
60 | export default withAuthenticator(App, { signUpConfig });
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | ReactDOM.unmountComponentAtNode(div);
9 | });
10 |
--------------------------------------------------------------------------------
/src/Device.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import clsx from 'clsx';
4 | import { makeStyles } from '@material-ui/core/styles';
5 | import Card from '@material-ui/core/Card';
6 | import CardActions from '@material-ui/core/CardActions';
7 | import CardContent from '@material-ui/core/CardContent';
8 | import CardMedia from '@material-ui/core/CardMedia';
9 | import Button from '@material-ui/core/Button';
10 | import Typography from '@material-ui/core/Typography';
11 | import { Grid } from '@material-ui/core';
12 | import {API, Auth, graphqlOperation} from "aws-amplify";
13 | import * as queries from "./graphql/queries";
14 | import * as mutations from "./graphql/mutations";
15 | import { Connect } from "aws-amplify-react";
16 | import Snackbar from '@material-ui/core/Snackbar';
17 | import SnackbarContent from '@material-ui/core/SnackbarContent';
18 | import {amber, green} from "@material-ui/core/colors"
19 | import CheckCircleIcon from '@material-ui/icons/CheckCircle';
20 |
21 | const useStyles = makeStyles({
22 | card: {
23 | maxWidth: 345,
24 | margin: 30
25 | },
26 | media: {
27 | height: 0,
28 | paddingTop: '56.25%'
29 | },
30 | });
31 |
32 |
33 |
34 | export default function Device() {
35 | const classes = useStyles();
36 | const [open, setOpen] = React.useState(false);
37 | const urlParams = new URLSearchParams(window.location.search);
38 | const thingName = urlParams.get('thingName');
39 |
40 | const bindDeviceToUser = async () => {
41 | const currentUser = await Auth.currentAuthenticatedUser();
42 |
43 | const deviceDetails = {
44 | thingName: thingName,
45 | username: currentUser.username,
46 | description: 'Smart Lamp'
47 | };
48 |
49 | const newDevice = await API.graphql(graphqlOperation(mutations.createDevice, {input: deviceDetails}));
50 | setOpen(true)
51 |
52 | console.log(newDevice)
53 | };
54 |
55 | const unbindDevice = async () => {
56 |
57 | const oldDevice = await API.graphql(graphqlOperation(mutations.deleteDevice, {input: {thingName: thingName}}));
58 | setOpen(true)
59 |
60 | console.log(oldDevice)
61 | };
62 |
63 |
64 | const CardView = ({ device }) => (
65 |
66 |
67 |
71 |
72 |
73 | Smart Lamp
74 |
75 |
76 | Smart lamp controlled to Alexa.
77 | Click the button to bind to your account.
78 |
79 |
80 |
81 | {(() => {
82 | if (device && device.username) {
83 | return (
84 |
87 | )
88 | } else {
89 | return (
90 |
93 | )
94 | }
95 | })()}
96 |
97 |
98 |
99 | );
100 |
101 | const useStyles1 = makeStyles(theme => ({
102 | success: {
103 | backgroundColor: green[600],
104 | },
105 | error: {
106 | backgroundColor: theme.palette.error.dark,
107 | },
108 | info: {
109 | backgroundColor: theme.palette.primary.main,
110 | },
111 | warning: {
112 | backgroundColor: amber[700],
113 | },
114 | icon: {
115 | fontSize: 20,
116 | },
117 | iconVariant: {
118 | opacity: 0.9,
119 | marginRight: theme.spacing(1),
120 | },
121 | message: {
122 | display: 'flex',
123 | alignItems: 'center',
124 | },
125 | }));
126 |
127 | const variantIcon = {
128 | success: CheckCircleIcon
129 | };
130 |
131 | function MySnackbarContentWrapper(props) {
132 | const classes = useStyles1();
133 | const { className, message, onClose, variant, ...other } = props;
134 | const Icon = variantIcon[variant];
135 |
136 | return (
137 |
142 |
143 | {message}
144 |
145 | }
146 | {...other}
147 | />
148 | );
149 | }
150 |
151 | MySnackbarContentWrapper.propTypes = {
152 | className: PropTypes.string,
153 | message: PropTypes.string,
154 | onClose: PropTypes.func,
155 | variant: PropTypes.oneOf(['error', 'info', 'success', 'warning']).isRequired,
156 | };
157 |
158 |
159 | function handleClose(event, reason) {
160 | if (reason === 'clickaway') {
161 | return;
162 | }
163 |
164 | setOpen(false);
165 | }
166 |
167 |
168 | return (
169 |
170 |
179 |
184 |
185 |
186 | {({ data, error }) => {
187 | if (error || data === undefined || data === null) return (Error
);
188 | return ( );
189 | }}
190 |
191 |
192 | );
193 | }
194 |
--------------------------------------------------------------------------------
/src/graphql/mutations.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | // this is an auto generated file. This will be overwritten
3 |
4 | export const createDevice = /* GraphQL */ `
5 | mutation CreateDevice(
6 | $input: CreateDeviceInput!
7 | $condition: ModelDeviceConditionInput
8 | ) {
9 | createDevice(input: $input, condition: $condition) {
10 | thingName
11 | username
12 | description
13 | createdAt
14 | updatedAt
15 | }
16 | }
17 | `;
18 | export const updateDevice = /* GraphQL */ `
19 | mutation UpdateDevice(
20 | $input: UpdateDeviceInput!
21 | $condition: ModelDeviceConditionInput
22 | ) {
23 | updateDevice(input: $input, condition: $condition) {
24 | thingName
25 | username
26 | description
27 | createdAt
28 | updatedAt
29 | }
30 | }
31 | `;
32 | export const deleteDevice = /* GraphQL */ `
33 | mutation DeleteDevice(
34 | $input: DeleteDeviceInput!
35 | $condition: ModelDeviceConditionInput
36 | ) {
37 | deleteDevice(input: $input, condition: $condition) {
38 | thingName
39 | username
40 | description
41 | createdAt
42 | updatedAt
43 | }
44 | }
45 | `;
46 |
--------------------------------------------------------------------------------
/src/graphql/queries.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | // this is an auto generated file. This will be overwritten
3 |
4 | export const getDevice = /* GraphQL */ `
5 | query GetDevice($thingName: String!) {
6 | getDevice(thingName: $thingName) {
7 | thingName
8 | username
9 | description
10 | createdAt
11 | updatedAt
12 | }
13 | }
14 | `;
15 | export const listDevices = /* GraphQL */ `
16 | query ListDevices(
17 | $thingName: String
18 | $filter: ModelDeviceFilterInput
19 | $limit: Int
20 | $nextToken: String
21 | $sortDirection: ModelSortDirection
22 | ) {
23 | listDevices(
24 | thingName: $thingName
25 | filter: $filter
26 | limit: $limit
27 | nextToken: $nextToken
28 | sortDirection: $sortDirection
29 | ) {
30 | items {
31 | thingName
32 | username
33 | description
34 | createdAt
35 | updatedAt
36 | }
37 | nextToken
38 | }
39 | }
40 | `;
41 |
--------------------------------------------------------------------------------
/src/graphql/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "data" : {
3 | "__schema" : {
4 | "queryType" : {
5 | "name" : "Query"
6 | },
7 | "mutationType" : {
8 | "name" : "Mutation"
9 | },
10 | "subscriptionType" : {
11 | "name" : "Subscription"
12 | },
13 | "types" : [ {
14 | "kind" : "OBJECT",
15 | "name" : "Query",
16 | "description" : null,
17 | "fields" : [ {
18 | "name" : "getDevice",
19 | "description" : null,
20 | "args" : [ {
21 | "name" : "thingName",
22 | "description" : null,
23 | "type" : {
24 | "kind" : "NON_NULL",
25 | "name" : null,
26 | "ofType" : {
27 | "kind" : "SCALAR",
28 | "name" : "String",
29 | "ofType" : null
30 | }
31 | },
32 | "defaultValue" : null
33 | } ],
34 | "type" : {
35 | "kind" : "OBJECT",
36 | "name" : "Device",
37 | "ofType" : null
38 | },
39 | "isDeprecated" : false,
40 | "deprecationReason" : null
41 | }, {
42 | "name" : "listDevices",
43 | "description" : null,
44 | "args" : [ {
45 | "name" : "thingName",
46 | "description" : null,
47 | "type" : {
48 | "kind" : "SCALAR",
49 | "name" : "String",
50 | "ofType" : null
51 | },
52 | "defaultValue" : null
53 | }, {
54 | "name" : "filter",
55 | "description" : null,
56 | "type" : {
57 | "kind" : "INPUT_OBJECT",
58 | "name" : "ModelDeviceFilterInput",
59 | "ofType" : null
60 | },
61 | "defaultValue" : null
62 | }, {
63 | "name" : "limit",
64 | "description" : null,
65 | "type" : {
66 | "kind" : "SCALAR",
67 | "name" : "Int",
68 | "ofType" : null
69 | },
70 | "defaultValue" : null
71 | }, {
72 | "name" : "nextToken",
73 | "description" : null,
74 | "type" : {
75 | "kind" : "SCALAR",
76 | "name" : "String",
77 | "ofType" : null
78 | },
79 | "defaultValue" : null
80 | }, {
81 | "name" : "sortDirection",
82 | "description" : null,
83 | "type" : {
84 | "kind" : "ENUM",
85 | "name" : "ModelSortDirection",
86 | "ofType" : null
87 | },
88 | "defaultValue" : null
89 | } ],
90 | "type" : {
91 | "kind" : "OBJECT",
92 | "name" : "ModelDeviceConnection",
93 | "ofType" : null
94 | },
95 | "isDeprecated" : false,
96 | "deprecationReason" : null
97 | } ],
98 | "inputFields" : null,
99 | "interfaces" : [ ],
100 | "enumValues" : null,
101 | "possibleTypes" : null
102 | }, {
103 | "kind" : "OBJECT",
104 | "name" : "Device",
105 | "description" : null,
106 | "fields" : [ {
107 | "name" : "thingName",
108 | "description" : null,
109 | "args" : [ ],
110 | "type" : {
111 | "kind" : "NON_NULL",
112 | "name" : null,
113 | "ofType" : {
114 | "kind" : "SCALAR",
115 | "name" : "String",
116 | "ofType" : null
117 | }
118 | },
119 | "isDeprecated" : false,
120 | "deprecationReason" : null
121 | }, {
122 | "name" : "username",
123 | "description" : null,
124 | "args" : [ ],
125 | "type" : {
126 | "kind" : "NON_NULL",
127 | "name" : null,
128 | "ofType" : {
129 | "kind" : "SCALAR",
130 | "name" : "String",
131 | "ofType" : null
132 | }
133 | },
134 | "isDeprecated" : false,
135 | "deprecationReason" : null
136 | }, {
137 | "name" : "description",
138 | "description" : null,
139 | "args" : [ ],
140 | "type" : {
141 | "kind" : "SCALAR",
142 | "name" : "String",
143 | "ofType" : null
144 | },
145 | "isDeprecated" : false,
146 | "deprecationReason" : null
147 | }, {
148 | "name" : "createdAt",
149 | "description" : null,
150 | "args" : [ ],
151 | "type" : {
152 | "kind" : "NON_NULL",
153 | "name" : null,
154 | "ofType" : {
155 | "kind" : "SCALAR",
156 | "name" : "AWSDateTime",
157 | "ofType" : null
158 | }
159 | },
160 | "isDeprecated" : false,
161 | "deprecationReason" : null
162 | }, {
163 | "name" : "updatedAt",
164 | "description" : null,
165 | "args" : [ ],
166 | "type" : {
167 | "kind" : "NON_NULL",
168 | "name" : null,
169 | "ofType" : {
170 | "kind" : "SCALAR",
171 | "name" : "AWSDateTime",
172 | "ofType" : null
173 | }
174 | },
175 | "isDeprecated" : false,
176 | "deprecationReason" : null
177 | } ],
178 | "inputFields" : null,
179 | "interfaces" : [ ],
180 | "enumValues" : null,
181 | "possibleTypes" : null
182 | }, {
183 | "kind" : "SCALAR",
184 | "name" : "String",
185 | "description" : "Built-in String",
186 | "fields" : null,
187 | "inputFields" : null,
188 | "interfaces" : null,
189 | "enumValues" : null,
190 | "possibleTypes" : null
191 | }, {
192 | "kind" : "SCALAR",
193 | "name" : "AWSDateTime",
194 | "description" : "The `AWSDateTime` scalar type provided by AWS AppSync, represents a valid ***extended*** [ISO 8601 DateTime](https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations) string. In other words, this scalar type accepts datetime strings of the form `YYYY-MM-DDThh:mm:ss.SSSZ`. The scalar can also accept \"negative years\" of the form `-YYYY` which correspond to years before `0000`. For example, \"**-2017-01-01T00:00Z**\" and \"**-9999-01-01T00:00Z**\" are both valid datetime strings. The field after the two digit seconds field is a nanoseconds field. It can accept between 1 and 9 digits. So, for example, \"**1970-01-01T12:00:00.2Z**\", \"**1970-01-01T12:00:00.277Z**\" and \"**1970-01-01T12:00:00.123456789Z**\" are all valid datetime strings. The seconds and nanoseconds fields are optional (the seconds field must be specified if the nanoseconds field is to be used). The [time zone offset](https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators) is compulsory for this scalar. The time zone offset must either be `Z` (representing the UTC time zone) or be in the format `±hh:mm:ss`. The seconds field in the timezone offset will be considered valid even though it is not part of the ISO 8601 standard.",
195 | "fields" : null,
196 | "inputFields" : null,
197 | "interfaces" : null,
198 | "enumValues" : null,
199 | "possibleTypes" : null
200 | }, {
201 | "kind" : "OBJECT",
202 | "name" : "ModelDeviceConnection",
203 | "description" : null,
204 | "fields" : [ {
205 | "name" : "items",
206 | "description" : null,
207 | "args" : [ ],
208 | "type" : {
209 | "kind" : "LIST",
210 | "name" : null,
211 | "ofType" : {
212 | "kind" : "OBJECT",
213 | "name" : "Device",
214 | "ofType" : null
215 | }
216 | },
217 | "isDeprecated" : false,
218 | "deprecationReason" : null
219 | }, {
220 | "name" : "nextToken",
221 | "description" : null,
222 | "args" : [ ],
223 | "type" : {
224 | "kind" : "SCALAR",
225 | "name" : "String",
226 | "ofType" : null
227 | },
228 | "isDeprecated" : false,
229 | "deprecationReason" : null
230 | } ],
231 | "inputFields" : null,
232 | "interfaces" : [ ],
233 | "enumValues" : null,
234 | "possibleTypes" : null
235 | }, {
236 | "kind" : "INPUT_OBJECT",
237 | "name" : "ModelDeviceFilterInput",
238 | "description" : null,
239 | "fields" : null,
240 | "inputFields" : [ {
241 | "name" : "thingName",
242 | "description" : null,
243 | "type" : {
244 | "kind" : "INPUT_OBJECT",
245 | "name" : "ModelStringInput",
246 | "ofType" : null
247 | },
248 | "defaultValue" : null
249 | }, {
250 | "name" : "username",
251 | "description" : null,
252 | "type" : {
253 | "kind" : "INPUT_OBJECT",
254 | "name" : "ModelStringInput",
255 | "ofType" : null
256 | },
257 | "defaultValue" : null
258 | }, {
259 | "name" : "description",
260 | "description" : null,
261 | "type" : {
262 | "kind" : "INPUT_OBJECT",
263 | "name" : "ModelStringInput",
264 | "ofType" : null
265 | },
266 | "defaultValue" : null
267 | }, {
268 | "name" : "and",
269 | "description" : null,
270 | "type" : {
271 | "kind" : "LIST",
272 | "name" : null,
273 | "ofType" : {
274 | "kind" : "INPUT_OBJECT",
275 | "name" : "ModelDeviceFilterInput",
276 | "ofType" : null
277 | }
278 | },
279 | "defaultValue" : null
280 | }, {
281 | "name" : "or",
282 | "description" : null,
283 | "type" : {
284 | "kind" : "LIST",
285 | "name" : null,
286 | "ofType" : {
287 | "kind" : "INPUT_OBJECT",
288 | "name" : "ModelDeviceFilterInput",
289 | "ofType" : null
290 | }
291 | },
292 | "defaultValue" : null
293 | }, {
294 | "name" : "not",
295 | "description" : null,
296 | "type" : {
297 | "kind" : "INPUT_OBJECT",
298 | "name" : "ModelDeviceFilterInput",
299 | "ofType" : null
300 | },
301 | "defaultValue" : null
302 | } ],
303 | "interfaces" : null,
304 | "enumValues" : null,
305 | "possibleTypes" : null
306 | }, {
307 | "kind" : "INPUT_OBJECT",
308 | "name" : "ModelStringInput",
309 | "description" : null,
310 | "fields" : null,
311 | "inputFields" : [ {
312 | "name" : "ne",
313 | "description" : null,
314 | "type" : {
315 | "kind" : "SCALAR",
316 | "name" : "String",
317 | "ofType" : null
318 | },
319 | "defaultValue" : null
320 | }, {
321 | "name" : "eq",
322 | "description" : null,
323 | "type" : {
324 | "kind" : "SCALAR",
325 | "name" : "String",
326 | "ofType" : null
327 | },
328 | "defaultValue" : null
329 | }, {
330 | "name" : "le",
331 | "description" : null,
332 | "type" : {
333 | "kind" : "SCALAR",
334 | "name" : "String",
335 | "ofType" : null
336 | },
337 | "defaultValue" : null
338 | }, {
339 | "name" : "lt",
340 | "description" : null,
341 | "type" : {
342 | "kind" : "SCALAR",
343 | "name" : "String",
344 | "ofType" : null
345 | },
346 | "defaultValue" : null
347 | }, {
348 | "name" : "ge",
349 | "description" : null,
350 | "type" : {
351 | "kind" : "SCALAR",
352 | "name" : "String",
353 | "ofType" : null
354 | },
355 | "defaultValue" : null
356 | }, {
357 | "name" : "gt",
358 | "description" : null,
359 | "type" : {
360 | "kind" : "SCALAR",
361 | "name" : "String",
362 | "ofType" : null
363 | },
364 | "defaultValue" : null
365 | }, {
366 | "name" : "contains",
367 | "description" : null,
368 | "type" : {
369 | "kind" : "SCALAR",
370 | "name" : "String",
371 | "ofType" : null
372 | },
373 | "defaultValue" : null
374 | }, {
375 | "name" : "notContains",
376 | "description" : null,
377 | "type" : {
378 | "kind" : "SCALAR",
379 | "name" : "String",
380 | "ofType" : null
381 | },
382 | "defaultValue" : null
383 | }, {
384 | "name" : "between",
385 | "description" : null,
386 | "type" : {
387 | "kind" : "LIST",
388 | "name" : null,
389 | "ofType" : {
390 | "kind" : "SCALAR",
391 | "name" : "String",
392 | "ofType" : null
393 | }
394 | },
395 | "defaultValue" : null
396 | }, {
397 | "name" : "beginsWith",
398 | "description" : null,
399 | "type" : {
400 | "kind" : "SCALAR",
401 | "name" : "String",
402 | "ofType" : null
403 | },
404 | "defaultValue" : null
405 | }, {
406 | "name" : "attributeExists",
407 | "description" : null,
408 | "type" : {
409 | "kind" : "SCALAR",
410 | "name" : "Boolean",
411 | "ofType" : null
412 | },
413 | "defaultValue" : null
414 | }, {
415 | "name" : "attributeType",
416 | "description" : null,
417 | "type" : {
418 | "kind" : "ENUM",
419 | "name" : "ModelAttributeTypes",
420 | "ofType" : null
421 | },
422 | "defaultValue" : null
423 | }, {
424 | "name" : "size",
425 | "description" : null,
426 | "type" : {
427 | "kind" : "INPUT_OBJECT",
428 | "name" : "ModelSizeInput",
429 | "ofType" : null
430 | },
431 | "defaultValue" : null
432 | } ],
433 | "interfaces" : null,
434 | "enumValues" : null,
435 | "possibleTypes" : null
436 | }, {
437 | "kind" : "SCALAR",
438 | "name" : "Boolean",
439 | "description" : "Built-in Boolean",
440 | "fields" : null,
441 | "inputFields" : null,
442 | "interfaces" : null,
443 | "enumValues" : null,
444 | "possibleTypes" : null
445 | }, {
446 | "kind" : "ENUM",
447 | "name" : "ModelAttributeTypes",
448 | "description" : null,
449 | "fields" : null,
450 | "inputFields" : null,
451 | "interfaces" : null,
452 | "enumValues" : [ {
453 | "name" : "binary",
454 | "description" : null,
455 | "isDeprecated" : false,
456 | "deprecationReason" : null
457 | }, {
458 | "name" : "binarySet",
459 | "description" : null,
460 | "isDeprecated" : false,
461 | "deprecationReason" : null
462 | }, {
463 | "name" : "bool",
464 | "description" : null,
465 | "isDeprecated" : false,
466 | "deprecationReason" : null
467 | }, {
468 | "name" : "list",
469 | "description" : null,
470 | "isDeprecated" : false,
471 | "deprecationReason" : null
472 | }, {
473 | "name" : "map",
474 | "description" : null,
475 | "isDeprecated" : false,
476 | "deprecationReason" : null
477 | }, {
478 | "name" : "number",
479 | "description" : null,
480 | "isDeprecated" : false,
481 | "deprecationReason" : null
482 | }, {
483 | "name" : "numberSet",
484 | "description" : null,
485 | "isDeprecated" : false,
486 | "deprecationReason" : null
487 | }, {
488 | "name" : "string",
489 | "description" : null,
490 | "isDeprecated" : false,
491 | "deprecationReason" : null
492 | }, {
493 | "name" : "stringSet",
494 | "description" : null,
495 | "isDeprecated" : false,
496 | "deprecationReason" : null
497 | }, {
498 | "name" : "_null",
499 | "description" : null,
500 | "isDeprecated" : false,
501 | "deprecationReason" : null
502 | } ],
503 | "possibleTypes" : null
504 | }, {
505 | "kind" : "INPUT_OBJECT",
506 | "name" : "ModelSizeInput",
507 | "description" : null,
508 | "fields" : null,
509 | "inputFields" : [ {
510 | "name" : "ne",
511 | "description" : null,
512 | "type" : {
513 | "kind" : "SCALAR",
514 | "name" : "Int",
515 | "ofType" : null
516 | },
517 | "defaultValue" : null
518 | }, {
519 | "name" : "eq",
520 | "description" : null,
521 | "type" : {
522 | "kind" : "SCALAR",
523 | "name" : "Int",
524 | "ofType" : null
525 | },
526 | "defaultValue" : null
527 | }, {
528 | "name" : "le",
529 | "description" : null,
530 | "type" : {
531 | "kind" : "SCALAR",
532 | "name" : "Int",
533 | "ofType" : null
534 | },
535 | "defaultValue" : null
536 | }, {
537 | "name" : "lt",
538 | "description" : null,
539 | "type" : {
540 | "kind" : "SCALAR",
541 | "name" : "Int",
542 | "ofType" : null
543 | },
544 | "defaultValue" : null
545 | }, {
546 | "name" : "ge",
547 | "description" : null,
548 | "type" : {
549 | "kind" : "SCALAR",
550 | "name" : "Int",
551 | "ofType" : null
552 | },
553 | "defaultValue" : null
554 | }, {
555 | "name" : "gt",
556 | "description" : null,
557 | "type" : {
558 | "kind" : "SCALAR",
559 | "name" : "Int",
560 | "ofType" : null
561 | },
562 | "defaultValue" : null
563 | }, {
564 | "name" : "between",
565 | "description" : null,
566 | "type" : {
567 | "kind" : "LIST",
568 | "name" : null,
569 | "ofType" : {
570 | "kind" : "SCALAR",
571 | "name" : "Int",
572 | "ofType" : null
573 | }
574 | },
575 | "defaultValue" : null
576 | } ],
577 | "interfaces" : null,
578 | "enumValues" : null,
579 | "possibleTypes" : null
580 | }, {
581 | "kind" : "SCALAR",
582 | "name" : "Int",
583 | "description" : "Built-in Int",
584 | "fields" : null,
585 | "inputFields" : null,
586 | "interfaces" : null,
587 | "enumValues" : null,
588 | "possibleTypes" : null
589 | }, {
590 | "kind" : "ENUM",
591 | "name" : "ModelSortDirection",
592 | "description" : null,
593 | "fields" : null,
594 | "inputFields" : null,
595 | "interfaces" : null,
596 | "enumValues" : [ {
597 | "name" : "ASC",
598 | "description" : null,
599 | "isDeprecated" : false,
600 | "deprecationReason" : null
601 | }, {
602 | "name" : "DESC",
603 | "description" : null,
604 | "isDeprecated" : false,
605 | "deprecationReason" : null
606 | } ],
607 | "possibleTypes" : null
608 | }, {
609 | "kind" : "OBJECT",
610 | "name" : "Mutation",
611 | "description" : null,
612 | "fields" : [ {
613 | "name" : "createDevice",
614 | "description" : null,
615 | "args" : [ {
616 | "name" : "input",
617 | "description" : null,
618 | "type" : {
619 | "kind" : "NON_NULL",
620 | "name" : null,
621 | "ofType" : {
622 | "kind" : "INPUT_OBJECT",
623 | "name" : "CreateDeviceInput",
624 | "ofType" : null
625 | }
626 | },
627 | "defaultValue" : null
628 | }, {
629 | "name" : "condition",
630 | "description" : null,
631 | "type" : {
632 | "kind" : "INPUT_OBJECT",
633 | "name" : "ModelDeviceConditionInput",
634 | "ofType" : null
635 | },
636 | "defaultValue" : null
637 | } ],
638 | "type" : {
639 | "kind" : "OBJECT",
640 | "name" : "Device",
641 | "ofType" : null
642 | },
643 | "isDeprecated" : false,
644 | "deprecationReason" : null
645 | }, {
646 | "name" : "updateDevice",
647 | "description" : null,
648 | "args" : [ {
649 | "name" : "input",
650 | "description" : null,
651 | "type" : {
652 | "kind" : "NON_NULL",
653 | "name" : null,
654 | "ofType" : {
655 | "kind" : "INPUT_OBJECT",
656 | "name" : "UpdateDeviceInput",
657 | "ofType" : null
658 | }
659 | },
660 | "defaultValue" : null
661 | }, {
662 | "name" : "condition",
663 | "description" : null,
664 | "type" : {
665 | "kind" : "INPUT_OBJECT",
666 | "name" : "ModelDeviceConditionInput",
667 | "ofType" : null
668 | },
669 | "defaultValue" : null
670 | } ],
671 | "type" : {
672 | "kind" : "OBJECT",
673 | "name" : "Device",
674 | "ofType" : null
675 | },
676 | "isDeprecated" : false,
677 | "deprecationReason" : null
678 | }, {
679 | "name" : "deleteDevice",
680 | "description" : null,
681 | "args" : [ {
682 | "name" : "input",
683 | "description" : null,
684 | "type" : {
685 | "kind" : "NON_NULL",
686 | "name" : null,
687 | "ofType" : {
688 | "kind" : "INPUT_OBJECT",
689 | "name" : "DeleteDeviceInput",
690 | "ofType" : null
691 | }
692 | },
693 | "defaultValue" : null
694 | }, {
695 | "name" : "condition",
696 | "description" : null,
697 | "type" : {
698 | "kind" : "INPUT_OBJECT",
699 | "name" : "ModelDeviceConditionInput",
700 | "ofType" : null
701 | },
702 | "defaultValue" : null
703 | } ],
704 | "type" : {
705 | "kind" : "OBJECT",
706 | "name" : "Device",
707 | "ofType" : null
708 | },
709 | "isDeprecated" : false,
710 | "deprecationReason" : null
711 | } ],
712 | "inputFields" : null,
713 | "interfaces" : [ ],
714 | "enumValues" : null,
715 | "possibleTypes" : null
716 | }, {
717 | "kind" : "INPUT_OBJECT",
718 | "name" : "CreateDeviceInput",
719 | "description" : null,
720 | "fields" : null,
721 | "inputFields" : [ {
722 | "name" : "thingName",
723 | "description" : null,
724 | "type" : {
725 | "kind" : "NON_NULL",
726 | "name" : null,
727 | "ofType" : {
728 | "kind" : "SCALAR",
729 | "name" : "String",
730 | "ofType" : null
731 | }
732 | },
733 | "defaultValue" : null
734 | }, {
735 | "name" : "username",
736 | "description" : null,
737 | "type" : {
738 | "kind" : "NON_NULL",
739 | "name" : null,
740 | "ofType" : {
741 | "kind" : "SCALAR",
742 | "name" : "String",
743 | "ofType" : null
744 | }
745 | },
746 | "defaultValue" : null
747 | }, {
748 | "name" : "description",
749 | "description" : null,
750 | "type" : {
751 | "kind" : "SCALAR",
752 | "name" : "String",
753 | "ofType" : null
754 | },
755 | "defaultValue" : null
756 | } ],
757 | "interfaces" : null,
758 | "enumValues" : null,
759 | "possibleTypes" : null
760 | }, {
761 | "kind" : "INPUT_OBJECT",
762 | "name" : "ModelDeviceConditionInput",
763 | "description" : null,
764 | "fields" : null,
765 | "inputFields" : [ {
766 | "name" : "username",
767 | "description" : null,
768 | "type" : {
769 | "kind" : "INPUT_OBJECT",
770 | "name" : "ModelStringInput",
771 | "ofType" : null
772 | },
773 | "defaultValue" : null
774 | }, {
775 | "name" : "description",
776 | "description" : null,
777 | "type" : {
778 | "kind" : "INPUT_OBJECT",
779 | "name" : "ModelStringInput",
780 | "ofType" : null
781 | },
782 | "defaultValue" : null
783 | }, {
784 | "name" : "and",
785 | "description" : null,
786 | "type" : {
787 | "kind" : "LIST",
788 | "name" : null,
789 | "ofType" : {
790 | "kind" : "INPUT_OBJECT",
791 | "name" : "ModelDeviceConditionInput",
792 | "ofType" : null
793 | }
794 | },
795 | "defaultValue" : null
796 | }, {
797 | "name" : "or",
798 | "description" : null,
799 | "type" : {
800 | "kind" : "LIST",
801 | "name" : null,
802 | "ofType" : {
803 | "kind" : "INPUT_OBJECT",
804 | "name" : "ModelDeviceConditionInput",
805 | "ofType" : null
806 | }
807 | },
808 | "defaultValue" : null
809 | }, {
810 | "name" : "not",
811 | "description" : null,
812 | "type" : {
813 | "kind" : "INPUT_OBJECT",
814 | "name" : "ModelDeviceConditionInput",
815 | "ofType" : null
816 | },
817 | "defaultValue" : null
818 | } ],
819 | "interfaces" : null,
820 | "enumValues" : null,
821 | "possibleTypes" : null
822 | }, {
823 | "kind" : "INPUT_OBJECT",
824 | "name" : "UpdateDeviceInput",
825 | "description" : null,
826 | "fields" : null,
827 | "inputFields" : [ {
828 | "name" : "thingName",
829 | "description" : null,
830 | "type" : {
831 | "kind" : "NON_NULL",
832 | "name" : null,
833 | "ofType" : {
834 | "kind" : "SCALAR",
835 | "name" : "String",
836 | "ofType" : null
837 | }
838 | },
839 | "defaultValue" : null
840 | }, {
841 | "name" : "username",
842 | "description" : null,
843 | "type" : {
844 | "kind" : "SCALAR",
845 | "name" : "String",
846 | "ofType" : null
847 | },
848 | "defaultValue" : null
849 | }, {
850 | "name" : "description",
851 | "description" : null,
852 | "type" : {
853 | "kind" : "SCALAR",
854 | "name" : "String",
855 | "ofType" : null
856 | },
857 | "defaultValue" : null
858 | } ],
859 | "interfaces" : null,
860 | "enumValues" : null,
861 | "possibleTypes" : null
862 | }, {
863 | "kind" : "INPUT_OBJECT",
864 | "name" : "DeleteDeviceInput",
865 | "description" : null,
866 | "fields" : null,
867 | "inputFields" : [ {
868 | "name" : "thingName",
869 | "description" : null,
870 | "type" : {
871 | "kind" : "NON_NULL",
872 | "name" : null,
873 | "ofType" : {
874 | "kind" : "SCALAR",
875 | "name" : "String",
876 | "ofType" : null
877 | }
878 | },
879 | "defaultValue" : null
880 | } ],
881 | "interfaces" : null,
882 | "enumValues" : null,
883 | "possibleTypes" : null
884 | }, {
885 | "kind" : "OBJECT",
886 | "name" : "Subscription",
887 | "description" : null,
888 | "fields" : [ {
889 | "name" : "onCreateDevice",
890 | "description" : null,
891 | "args" : [ ],
892 | "type" : {
893 | "kind" : "OBJECT",
894 | "name" : "Device",
895 | "ofType" : null
896 | },
897 | "isDeprecated" : false,
898 | "deprecationReason" : null
899 | }, {
900 | "name" : "onUpdateDevice",
901 | "description" : null,
902 | "args" : [ ],
903 | "type" : {
904 | "kind" : "OBJECT",
905 | "name" : "Device",
906 | "ofType" : null
907 | },
908 | "isDeprecated" : false,
909 | "deprecationReason" : null
910 | }, {
911 | "name" : "onDeleteDevice",
912 | "description" : null,
913 | "args" : [ ],
914 | "type" : {
915 | "kind" : "OBJECT",
916 | "name" : "Device",
917 | "ofType" : null
918 | },
919 | "isDeprecated" : false,
920 | "deprecationReason" : null
921 | } ],
922 | "inputFields" : null,
923 | "interfaces" : [ ],
924 | "enumValues" : null,
925 | "possibleTypes" : null
926 | }, {
927 | "kind" : "INPUT_OBJECT",
928 | "name" : "ModelBooleanInput",
929 | "description" : null,
930 | "fields" : null,
931 | "inputFields" : [ {
932 | "name" : "ne",
933 | "description" : null,
934 | "type" : {
935 | "kind" : "SCALAR",
936 | "name" : "Boolean",
937 | "ofType" : null
938 | },
939 | "defaultValue" : null
940 | }, {
941 | "name" : "eq",
942 | "description" : null,
943 | "type" : {
944 | "kind" : "SCALAR",
945 | "name" : "Boolean",
946 | "ofType" : null
947 | },
948 | "defaultValue" : null
949 | }, {
950 | "name" : "attributeExists",
951 | "description" : null,
952 | "type" : {
953 | "kind" : "SCALAR",
954 | "name" : "Boolean",
955 | "ofType" : null
956 | },
957 | "defaultValue" : null
958 | }, {
959 | "name" : "attributeType",
960 | "description" : null,
961 | "type" : {
962 | "kind" : "ENUM",
963 | "name" : "ModelAttributeTypes",
964 | "ofType" : null
965 | },
966 | "defaultValue" : null
967 | } ],
968 | "interfaces" : null,
969 | "enumValues" : null,
970 | "possibleTypes" : null
971 | }, {
972 | "kind" : "INPUT_OBJECT",
973 | "name" : "ModelIDInput",
974 | "description" : null,
975 | "fields" : null,
976 | "inputFields" : [ {
977 | "name" : "ne",
978 | "description" : null,
979 | "type" : {
980 | "kind" : "SCALAR",
981 | "name" : "ID",
982 | "ofType" : null
983 | },
984 | "defaultValue" : null
985 | }, {
986 | "name" : "eq",
987 | "description" : null,
988 | "type" : {
989 | "kind" : "SCALAR",
990 | "name" : "ID",
991 | "ofType" : null
992 | },
993 | "defaultValue" : null
994 | }, {
995 | "name" : "le",
996 | "description" : null,
997 | "type" : {
998 | "kind" : "SCALAR",
999 | "name" : "ID",
1000 | "ofType" : null
1001 | },
1002 | "defaultValue" : null
1003 | }, {
1004 | "name" : "lt",
1005 | "description" : null,
1006 | "type" : {
1007 | "kind" : "SCALAR",
1008 | "name" : "ID",
1009 | "ofType" : null
1010 | },
1011 | "defaultValue" : null
1012 | }, {
1013 | "name" : "ge",
1014 | "description" : null,
1015 | "type" : {
1016 | "kind" : "SCALAR",
1017 | "name" : "ID",
1018 | "ofType" : null
1019 | },
1020 | "defaultValue" : null
1021 | }, {
1022 | "name" : "gt",
1023 | "description" : null,
1024 | "type" : {
1025 | "kind" : "SCALAR",
1026 | "name" : "ID",
1027 | "ofType" : null
1028 | },
1029 | "defaultValue" : null
1030 | }, {
1031 | "name" : "contains",
1032 | "description" : null,
1033 | "type" : {
1034 | "kind" : "SCALAR",
1035 | "name" : "ID",
1036 | "ofType" : null
1037 | },
1038 | "defaultValue" : null
1039 | }, {
1040 | "name" : "notContains",
1041 | "description" : null,
1042 | "type" : {
1043 | "kind" : "SCALAR",
1044 | "name" : "ID",
1045 | "ofType" : null
1046 | },
1047 | "defaultValue" : null
1048 | }, {
1049 | "name" : "between",
1050 | "description" : null,
1051 | "type" : {
1052 | "kind" : "LIST",
1053 | "name" : null,
1054 | "ofType" : {
1055 | "kind" : "SCALAR",
1056 | "name" : "ID",
1057 | "ofType" : null
1058 | }
1059 | },
1060 | "defaultValue" : null
1061 | }, {
1062 | "name" : "beginsWith",
1063 | "description" : null,
1064 | "type" : {
1065 | "kind" : "SCALAR",
1066 | "name" : "ID",
1067 | "ofType" : null
1068 | },
1069 | "defaultValue" : null
1070 | }, {
1071 | "name" : "attributeExists",
1072 | "description" : null,
1073 | "type" : {
1074 | "kind" : "SCALAR",
1075 | "name" : "Boolean",
1076 | "ofType" : null
1077 | },
1078 | "defaultValue" : null
1079 | }, {
1080 | "name" : "attributeType",
1081 | "description" : null,
1082 | "type" : {
1083 | "kind" : "ENUM",
1084 | "name" : "ModelAttributeTypes",
1085 | "ofType" : null
1086 | },
1087 | "defaultValue" : null
1088 | }, {
1089 | "name" : "size",
1090 | "description" : null,
1091 | "type" : {
1092 | "kind" : "INPUT_OBJECT",
1093 | "name" : "ModelSizeInput",
1094 | "ofType" : null
1095 | },
1096 | "defaultValue" : null
1097 | } ],
1098 | "interfaces" : null,
1099 | "enumValues" : null,
1100 | "possibleTypes" : null
1101 | }, {
1102 | "kind" : "SCALAR",
1103 | "name" : "ID",
1104 | "description" : "Built-in ID",
1105 | "fields" : null,
1106 | "inputFields" : null,
1107 | "interfaces" : null,
1108 | "enumValues" : null,
1109 | "possibleTypes" : null
1110 | }, {
1111 | "kind" : "INPUT_OBJECT",
1112 | "name" : "ModelFloatInput",
1113 | "description" : null,
1114 | "fields" : null,
1115 | "inputFields" : [ {
1116 | "name" : "ne",
1117 | "description" : null,
1118 | "type" : {
1119 | "kind" : "SCALAR",
1120 | "name" : "Float",
1121 | "ofType" : null
1122 | },
1123 | "defaultValue" : null
1124 | }, {
1125 | "name" : "eq",
1126 | "description" : null,
1127 | "type" : {
1128 | "kind" : "SCALAR",
1129 | "name" : "Float",
1130 | "ofType" : null
1131 | },
1132 | "defaultValue" : null
1133 | }, {
1134 | "name" : "le",
1135 | "description" : null,
1136 | "type" : {
1137 | "kind" : "SCALAR",
1138 | "name" : "Float",
1139 | "ofType" : null
1140 | },
1141 | "defaultValue" : null
1142 | }, {
1143 | "name" : "lt",
1144 | "description" : null,
1145 | "type" : {
1146 | "kind" : "SCALAR",
1147 | "name" : "Float",
1148 | "ofType" : null
1149 | },
1150 | "defaultValue" : null
1151 | }, {
1152 | "name" : "ge",
1153 | "description" : null,
1154 | "type" : {
1155 | "kind" : "SCALAR",
1156 | "name" : "Float",
1157 | "ofType" : null
1158 | },
1159 | "defaultValue" : null
1160 | }, {
1161 | "name" : "gt",
1162 | "description" : null,
1163 | "type" : {
1164 | "kind" : "SCALAR",
1165 | "name" : "Float",
1166 | "ofType" : null
1167 | },
1168 | "defaultValue" : null
1169 | }, {
1170 | "name" : "between",
1171 | "description" : null,
1172 | "type" : {
1173 | "kind" : "LIST",
1174 | "name" : null,
1175 | "ofType" : {
1176 | "kind" : "SCALAR",
1177 | "name" : "Float",
1178 | "ofType" : null
1179 | }
1180 | },
1181 | "defaultValue" : null
1182 | }, {
1183 | "name" : "attributeExists",
1184 | "description" : null,
1185 | "type" : {
1186 | "kind" : "SCALAR",
1187 | "name" : "Boolean",
1188 | "ofType" : null
1189 | },
1190 | "defaultValue" : null
1191 | }, {
1192 | "name" : "attributeType",
1193 | "description" : null,
1194 | "type" : {
1195 | "kind" : "ENUM",
1196 | "name" : "ModelAttributeTypes",
1197 | "ofType" : null
1198 | },
1199 | "defaultValue" : null
1200 | } ],
1201 | "interfaces" : null,
1202 | "enumValues" : null,
1203 | "possibleTypes" : null
1204 | }, {
1205 | "kind" : "SCALAR",
1206 | "name" : "Float",
1207 | "description" : "Built-in Float",
1208 | "fields" : null,
1209 | "inputFields" : null,
1210 | "interfaces" : null,
1211 | "enumValues" : null,
1212 | "possibleTypes" : null
1213 | }, {
1214 | "kind" : "INPUT_OBJECT",
1215 | "name" : "ModelStringKeyConditionInput",
1216 | "description" : null,
1217 | "fields" : null,
1218 | "inputFields" : [ {
1219 | "name" : "eq",
1220 | "description" : null,
1221 | "type" : {
1222 | "kind" : "SCALAR",
1223 | "name" : "String",
1224 | "ofType" : null
1225 | },
1226 | "defaultValue" : null
1227 | }, {
1228 | "name" : "le",
1229 | "description" : null,
1230 | "type" : {
1231 | "kind" : "SCALAR",
1232 | "name" : "String",
1233 | "ofType" : null
1234 | },
1235 | "defaultValue" : null
1236 | }, {
1237 | "name" : "lt",
1238 | "description" : null,
1239 | "type" : {
1240 | "kind" : "SCALAR",
1241 | "name" : "String",
1242 | "ofType" : null
1243 | },
1244 | "defaultValue" : null
1245 | }, {
1246 | "name" : "ge",
1247 | "description" : null,
1248 | "type" : {
1249 | "kind" : "SCALAR",
1250 | "name" : "String",
1251 | "ofType" : null
1252 | },
1253 | "defaultValue" : null
1254 | }, {
1255 | "name" : "gt",
1256 | "description" : null,
1257 | "type" : {
1258 | "kind" : "SCALAR",
1259 | "name" : "String",
1260 | "ofType" : null
1261 | },
1262 | "defaultValue" : null
1263 | }, {
1264 | "name" : "between",
1265 | "description" : null,
1266 | "type" : {
1267 | "kind" : "LIST",
1268 | "name" : null,
1269 | "ofType" : {
1270 | "kind" : "SCALAR",
1271 | "name" : "String",
1272 | "ofType" : null
1273 | }
1274 | },
1275 | "defaultValue" : null
1276 | }, {
1277 | "name" : "beginsWith",
1278 | "description" : null,
1279 | "type" : {
1280 | "kind" : "SCALAR",
1281 | "name" : "String",
1282 | "ofType" : null
1283 | },
1284 | "defaultValue" : null
1285 | } ],
1286 | "interfaces" : null,
1287 | "enumValues" : null,
1288 | "possibleTypes" : null
1289 | }, {
1290 | "kind" : "INPUT_OBJECT",
1291 | "name" : "ModelIntInput",
1292 | "description" : null,
1293 | "fields" : null,
1294 | "inputFields" : [ {
1295 | "name" : "ne",
1296 | "description" : null,
1297 | "type" : {
1298 | "kind" : "SCALAR",
1299 | "name" : "Int",
1300 | "ofType" : null
1301 | },
1302 | "defaultValue" : null
1303 | }, {
1304 | "name" : "eq",
1305 | "description" : null,
1306 | "type" : {
1307 | "kind" : "SCALAR",
1308 | "name" : "Int",
1309 | "ofType" : null
1310 | },
1311 | "defaultValue" : null
1312 | }, {
1313 | "name" : "le",
1314 | "description" : null,
1315 | "type" : {
1316 | "kind" : "SCALAR",
1317 | "name" : "Int",
1318 | "ofType" : null
1319 | },
1320 | "defaultValue" : null
1321 | }, {
1322 | "name" : "lt",
1323 | "description" : null,
1324 | "type" : {
1325 | "kind" : "SCALAR",
1326 | "name" : "Int",
1327 | "ofType" : null
1328 | },
1329 | "defaultValue" : null
1330 | }, {
1331 | "name" : "ge",
1332 | "description" : null,
1333 | "type" : {
1334 | "kind" : "SCALAR",
1335 | "name" : "Int",
1336 | "ofType" : null
1337 | },
1338 | "defaultValue" : null
1339 | }, {
1340 | "name" : "gt",
1341 | "description" : null,
1342 | "type" : {
1343 | "kind" : "SCALAR",
1344 | "name" : "Int",
1345 | "ofType" : null
1346 | },
1347 | "defaultValue" : null
1348 | }, {
1349 | "name" : "between",
1350 | "description" : null,
1351 | "type" : {
1352 | "kind" : "LIST",
1353 | "name" : null,
1354 | "ofType" : {
1355 | "kind" : "SCALAR",
1356 | "name" : "Int",
1357 | "ofType" : null
1358 | }
1359 | },
1360 | "defaultValue" : null
1361 | }, {
1362 | "name" : "attributeExists",
1363 | "description" : null,
1364 | "type" : {
1365 | "kind" : "SCALAR",
1366 | "name" : "Boolean",
1367 | "ofType" : null
1368 | },
1369 | "defaultValue" : null
1370 | }, {
1371 | "name" : "attributeType",
1372 | "description" : null,
1373 | "type" : {
1374 | "kind" : "ENUM",
1375 | "name" : "ModelAttributeTypes",
1376 | "ofType" : null
1377 | },
1378 | "defaultValue" : null
1379 | } ],
1380 | "interfaces" : null,
1381 | "enumValues" : null,
1382 | "possibleTypes" : null
1383 | }, {
1384 | "kind" : "OBJECT",
1385 | "name" : "__Schema",
1386 | "description" : "A GraphQL Introspection defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, the entry points for query, mutation, and subscription operations.",
1387 | "fields" : [ {
1388 | "name" : "types",
1389 | "description" : "A list of all types supported by this server.",
1390 | "args" : [ ],
1391 | "type" : {
1392 | "kind" : "NON_NULL",
1393 | "name" : null,
1394 | "ofType" : {
1395 | "kind" : "LIST",
1396 | "name" : null,
1397 | "ofType" : {
1398 | "kind" : "NON_NULL",
1399 | "name" : null,
1400 | "ofType" : {
1401 | "kind" : "OBJECT",
1402 | "name" : "__Type",
1403 | "ofType" : null
1404 | }
1405 | }
1406 | }
1407 | },
1408 | "isDeprecated" : false,
1409 | "deprecationReason" : null
1410 | }, {
1411 | "name" : "queryType",
1412 | "description" : "The type that query operations will be rooted at.",
1413 | "args" : [ ],
1414 | "type" : {
1415 | "kind" : "NON_NULL",
1416 | "name" : null,
1417 | "ofType" : {
1418 | "kind" : "OBJECT",
1419 | "name" : "__Type",
1420 | "ofType" : null
1421 | }
1422 | },
1423 | "isDeprecated" : false,
1424 | "deprecationReason" : null
1425 | }, {
1426 | "name" : "mutationType",
1427 | "description" : "If this server supports mutation, the type that mutation operations will be rooted at.",
1428 | "args" : [ ],
1429 | "type" : {
1430 | "kind" : "OBJECT",
1431 | "name" : "__Type",
1432 | "ofType" : null
1433 | },
1434 | "isDeprecated" : false,
1435 | "deprecationReason" : null
1436 | }, {
1437 | "name" : "directives",
1438 | "description" : "'A list of all directives supported by this server.",
1439 | "args" : [ ],
1440 | "type" : {
1441 | "kind" : "NON_NULL",
1442 | "name" : null,
1443 | "ofType" : {
1444 | "kind" : "LIST",
1445 | "name" : null,
1446 | "ofType" : {
1447 | "kind" : "NON_NULL",
1448 | "name" : null,
1449 | "ofType" : {
1450 | "kind" : "OBJECT",
1451 | "name" : "__Directive",
1452 | "ofType" : null
1453 | }
1454 | }
1455 | }
1456 | },
1457 | "isDeprecated" : false,
1458 | "deprecationReason" : null
1459 | }, {
1460 | "name" : "subscriptionType",
1461 | "description" : "'If this server support subscription, the type that subscription operations will be rooted at.",
1462 | "args" : [ ],
1463 | "type" : {
1464 | "kind" : "OBJECT",
1465 | "name" : "__Type",
1466 | "ofType" : null
1467 | },
1468 | "isDeprecated" : false,
1469 | "deprecationReason" : null
1470 | } ],
1471 | "inputFields" : null,
1472 | "interfaces" : [ ],
1473 | "enumValues" : null,
1474 | "possibleTypes" : null
1475 | }, {
1476 | "kind" : "OBJECT",
1477 | "name" : "__Type",
1478 | "description" : null,
1479 | "fields" : [ {
1480 | "name" : "kind",
1481 | "description" : null,
1482 | "args" : [ ],
1483 | "type" : {
1484 | "kind" : "NON_NULL",
1485 | "name" : null,
1486 | "ofType" : {
1487 | "kind" : "ENUM",
1488 | "name" : "__TypeKind",
1489 | "ofType" : null
1490 | }
1491 | },
1492 | "isDeprecated" : false,
1493 | "deprecationReason" : null
1494 | }, {
1495 | "name" : "name",
1496 | "description" : null,
1497 | "args" : [ ],
1498 | "type" : {
1499 | "kind" : "SCALAR",
1500 | "name" : "String",
1501 | "ofType" : null
1502 | },
1503 | "isDeprecated" : false,
1504 | "deprecationReason" : null
1505 | }, {
1506 | "name" : "description",
1507 | "description" : null,
1508 | "args" : [ ],
1509 | "type" : {
1510 | "kind" : "SCALAR",
1511 | "name" : "String",
1512 | "ofType" : null
1513 | },
1514 | "isDeprecated" : false,
1515 | "deprecationReason" : null
1516 | }, {
1517 | "name" : "fields",
1518 | "description" : null,
1519 | "args" : [ {
1520 | "name" : "includeDeprecated",
1521 | "description" : null,
1522 | "type" : {
1523 | "kind" : "SCALAR",
1524 | "name" : "Boolean",
1525 | "ofType" : null
1526 | },
1527 | "defaultValue" : "false"
1528 | } ],
1529 | "type" : {
1530 | "kind" : "LIST",
1531 | "name" : null,
1532 | "ofType" : {
1533 | "kind" : "NON_NULL",
1534 | "name" : null,
1535 | "ofType" : {
1536 | "kind" : "OBJECT",
1537 | "name" : "__Field",
1538 | "ofType" : null
1539 | }
1540 | }
1541 | },
1542 | "isDeprecated" : false,
1543 | "deprecationReason" : null
1544 | }, {
1545 | "name" : "interfaces",
1546 | "description" : null,
1547 | "args" : [ ],
1548 | "type" : {
1549 | "kind" : "LIST",
1550 | "name" : null,
1551 | "ofType" : {
1552 | "kind" : "NON_NULL",
1553 | "name" : null,
1554 | "ofType" : {
1555 | "kind" : "OBJECT",
1556 | "name" : "__Type",
1557 | "ofType" : null
1558 | }
1559 | }
1560 | },
1561 | "isDeprecated" : false,
1562 | "deprecationReason" : null
1563 | }, {
1564 | "name" : "possibleTypes",
1565 | "description" : null,
1566 | "args" : [ ],
1567 | "type" : {
1568 | "kind" : "LIST",
1569 | "name" : null,
1570 | "ofType" : {
1571 | "kind" : "NON_NULL",
1572 | "name" : null,
1573 | "ofType" : {
1574 | "kind" : "OBJECT",
1575 | "name" : "__Type",
1576 | "ofType" : null
1577 | }
1578 | }
1579 | },
1580 | "isDeprecated" : false,
1581 | "deprecationReason" : null
1582 | }, {
1583 | "name" : "enumValues",
1584 | "description" : null,
1585 | "args" : [ {
1586 | "name" : "includeDeprecated",
1587 | "description" : null,
1588 | "type" : {
1589 | "kind" : "SCALAR",
1590 | "name" : "Boolean",
1591 | "ofType" : null
1592 | },
1593 | "defaultValue" : "false"
1594 | } ],
1595 | "type" : {
1596 | "kind" : "LIST",
1597 | "name" : null,
1598 | "ofType" : {
1599 | "kind" : "NON_NULL",
1600 | "name" : null,
1601 | "ofType" : {
1602 | "kind" : "OBJECT",
1603 | "name" : "__EnumValue",
1604 | "ofType" : null
1605 | }
1606 | }
1607 | },
1608 | "isDeprecated" : false,
1609 | "deprecationReason" : null
1610 | }, {
1611 | "name" : "inputFields",
1612 | "description" : null,
1613 | "args" : [ ],
1614 | "type" : {
1615 | "kind" : "LIST",
1616 | "name" : null,
1617 | "ofType" : {
1618 | "kind" : "NON_NULL",
1619 | "name" : null,
1620 | "ofType" : {
1621 | "kind" : "OBJECT",
1622 | "name" : "__InputValue",
1623 | "ofType" : null
1624 | }
1625 | }
1626 | },
1627 | "isDeprecated" : false,
1628 | "deprecationReason" : null
1629 | }, {
1630 | "name" : "ofType",
1631 | "description" : null,
1632 | "args" : [ ],
1633 | "type" : {
1634 | "kind" : "OBJECT",
1635 | "name" : "__Type",
1636 | "ofType" : null
1637 | },
1638 | "isDeprecated" : false,
1639 | "deprecationReason" : null
1640 | } ],
1641 | "inputFields" : null,
1642 | "interfaces" : [ ],
1643 | "enumValues" : null,
1644 | "possibleTypes" : null
1645 | }, {
1646 | "kind" : "ENUM",
1647 | "name" : "__TypeKind",
1648 | "description" : "An enum describing what kind of type a given __Type is",
1649 | "fields" : null,
1650 | "inputFields" : null,
1651 | "interfaces" : null,
1652 | "enumValues" : [ {
1653 | "name" : "SCALAR",
1654 | "description" : "Indicates this type is a scalar.",
1655 | "isDeprecated" : false,
1656 | "deprecationReason" : null
1657 | }, {
1658 | "name" : "OBJECT",
1659 | "description" : "Indicates this type is an object. `fields` and `interfaces` are valid fields.",
1660 | "isDeprecated" : false,
1661 | "deprecationReason" : null
1662 | }, {
1663 | "name" : "INTERFACE",
1664 | "description" : "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.",
1665 | "isDeprecated" : false,
1666 | "deprecationReason" : null
1667 | }, {
1668 | "name" : "UNION",
1669 | "description" : "Indicates this type is a union. `possibleTypes` is a valid field.",
1670 | "isDeprecated" : false,
1671 | "deprecationReason" : null
1672 | }, {
1673 | "name" : "ENUM",
1674 | "description" : "Indicates this type is an enum. `enumValues` is a valid field.",
1675 | "isDeprecated" : false,
1676 | "deprecationReason" : null
1677 | }, {
1678 | "name" : "INPUT_OBJECT",
1679 | "description" : "Indicates this type is an input object. `inputFields` is a valid field.",
1680 | "isDeprecated" : false,
1681 | "deprecationReason" : null
1682 | }, {
1683 | "name" : "LIST",
1684 | "description" : "Indicates this type is a list. `ofType` is a valid field.",
1685 | "isDeprecated" : false,
1686 | "deprecationReason" : null
1687 | }, {
1688 | "name" : "NON_NULL",
1689 | "description" : "Indicates this type is a non-null. `ofType` is a valid field.",
1690 | "isDeprecated" : false,
1691 | "deprecationReason" : null
1692 | } ],
1693 | "possibleTypes" : null
1694 | }, {
1695 | "kind" : "OBJECT",
1696 | "name" : "__Field",
1697 | "description" : null,
1698 | "fields" : [ {
1699 | "name" : "name",
1700 | "description" : null,
1701 | "args" : [ ],
1702 | "type" : {
1703 | "kind" : "NON_NULL",
1704 | "name" : null,
1705 | "ofType" : {
1706 | "kind" : "SCALAR",
1707 | "name" : "String",
1708 | "ofType" : null
1709 | }
1710 | },
1711 | "isDeprecated" : false,
1712 | "deprecationReason" : null
1713 | }, {
1714 | "name" : "description",
1715 | "description" : null,
1716 | "args" : [ ],
1717 | "type" : {
1718 | "kind" : "SCALAR",
1719 | "name" : "String",
1720 | "ofType" : null
1721 | },
1722 | "isDeprecated" : false,
1723 | "deprecationReason" : null
1724 | }, {
1725 | "name" : "args",
1726 | "description" : null,
1727 | "args" : [ ],
1728 | "type" : {
1729 | "kind" : "NON_NULL",
1730 | "name" : null,
1731 | "ofType" : {
1732 | "kind" : "LIST",
1733 | "name" : null,
1734 | "ofType" : {
1735 | "kind" : "NON_NULL",
1736 | "name" : null,
1737 | "ofType" : {
1738 | "kind" : "OBJECT",
1739 | "name" : "__InputValue",
1740 | "ofType" : null
1741 | }
1742 | }
1743 | }
1744 | },
1745 | "isDeprecated" : false,
1746 | "deprecationReason" : null
1747 | }, {
1748 | "name" : "type",
1749 | "description" : null,
1750 | "args" : [ ],
1751 | "type" : {
1752 | "kind" : "NON_NULL",
1753 | "name" : null,
1754 | "ofType" : {
1755 | "kind" : "OBJECT",
1756 | "name" : "__Type",
1757 | "ofType" : null
1758 | }
1759 | },
1760 | "isDeprecated" : false,
1761 | "deprecationReason" : null
1762 | }, {
1763 | "name" : "isDeprecated",
1764 | "description" : null,
1765 | "args" : [ ],
1766 | "type" : {
1767 | "kind" : "NON_NULL",
1768 | "name" : null,
1769 | "ofType" : {
1770 | "kind" : "SCALAR",
1771 | "name" : "Boolean",
1772 | "ofType" : null
1773 | }
1774 | },
1775 | "isDeprecated" : false,
1776 | "deprecationReason" : null
1777 | }, {
1778 | "name" : "deprecationReason",
1779 | "description" : null,
1780 | "args" : [ ],
1781 | "type" : {
1782 | "kind" : "SCALAR",
1783 | "name" : "String",
1784 | "ofType" : null
1785 | },
1786 | "isDeprecated" : false,
1787 | "deprecationReason" : null
1788 | } ],
1789 | "inputFields" : null,
1790 | "interfaces" : [ ],
1791 | "enumValues" : null,
1792 | "possibleTypes" : null
1793 | }, {
1794 | "kind" : "OBJECT",
1795 | "name" : "__InputValue",
1796 | "description" : null,
1797 | "fields" : [ {
1798 | "name" : "name",
1799 | "description" : null,
1800 | "args" : [ ],
1801 | "type" : {
1802 | "kind" : "NON_NULL",
1803 | "name" : null,
1804 | "ofType" : {
1805 | "kind" : "SCALAR",
1806 | "name" : "String",
1807 | "ofType" : null
1808 | }
1809 | },
1810 | "isDeprecated" : false,
1811 | "deprecationReason" : null
1812 | }, {
1813 | "name" : "description",
1814 | "description" : null,
1815 | "args" : [ ],
1816 | "type" : {
1817 | "kind" : "SCALAR",
1818 | "name" : "String",
1819 | "ofType" : null
1820 | },
1821 | "isDeprecated" : false,
1822 | "deprecationReason" : null
1823 | }, {
1824 | "name" : "type",
1825 | "description" : null,
1826 | "args" : [ ],
1827 | "type" : {
1828 | "kind" : "NON_NULL",
1829 | "name" : null,
1830 | "ofType" : {
1831 | "kind" : "OBJECT",
1832 | "name" : "__Type",
1833 | "ofType" : null
1834 | }
1835 | },
1836 | "isDeprecated" : false,
1837 | "deprecationReason" : null
1838 | }, {
1839 | "name" : "defaultValue",
1840 | "description" : null,
1841 | "args" : [ ],
1842 | "type" : {
1843 | "kind" : "SCALAR",
1844 | "name" : "String",
1845 | "ofType" : null
1846 | },
1847 | "isDeprecated" : false,
1848 | "deprecationReason" : null
1849 | } ],
1850 | "inputFields" : null,
1851 | "interfaces" : [ ],
1852 | "enumValues" : null,
1853 | "possibleTypes" : null
1854 | }, {
1855 | "kind" : "OBJECT",
1856 | "name" : "__EnumValue",
1857 | "description" : null,
1858 | "fields" : [ {
1859 | "name" : "name",
1860 | "description" : null,
1861 | "args" : [ ],
1862 | "type" : {
1863 | "kind" : "NON_NULL",
1864 | "name" : null,
1865 | "ofType" : {
1866 | "kind" : "SCALAR",
1867 | "name" : "String",
1868 | "ofType" : null
1869 | }
1870 | },
1871 | "isDeprecated" : false,
1872 | "deprecationReason" : null
1873 | }, {
1874 | "name" : "description",
1875 | "description" : null,
1876 | "args" : [ ],
1877 | "type" : {
1878 | "kind" : "SCALAR",
1879 | "name" : "String",
1880 | "ofType" : null
1881 | },
1882 | "isDeprecated" : false,
1883 | "deprecationReason" : null
1884 | }, {
1885 | "name" : "isDeprecated",
1886 | "description" : null,
1887 | "args" : [ ],
1888 | "type" : {
1889 | "kind" : "NON_NULL",
1890 | "name" : null,
1891 | "ofType" : {
1892 | "kind" : "SCALAR",
1893 | "name" : "Boolean",
1894 | "ofType" : null
1895 | }
1896 | },
1897 | "isDeprecated" : false,
1898 | "deprecationReason" : null
1899 | }, {
1900 | "name" : "deprecationReason",
1901 | "description" : null,
1902 | "args" : [ ],
1903 | "type" : {
1904 | "kind" : "SCALAR",
1905 | "name" : "String",
1906 | "ofType" : null
1907 | },
1908 | "isDeprecated" : false,
1909 | "deprecationReason" : null
1910 | } ],
1911 | "inputFields" : null,
1912 | "interfaces" : [ ],
1913 | "enumValues" : null,
1914 | "possibleTypes" : null
1915 | }, {
1916 | "kind" : "OBJECT",
1917 | "name" : "__Directive",
1918 | "description" : null,
1919 | "fields" : [ {
1920 | "name" : "name",
1921 | "description" : null,
1922 | "args" : [ ],
1923 | "type" : {
1924 | "kind" : "SCALAR",
1925 | "name" : "String",
1926 | "ofType" : null
1927 | },
1928 | "isDeprecated" : false,
1929 | "deprecationReason" : null
1930 | }, {
1931 | "name" : "description",
1932 | "description" : null,
1933 | "args" : [ ],
1934 | "type" : {
1935 | "kind" : "SCALAR",
1936 | "name" : "String",
1937 | "ofType" : null
1938 | },
1939 | "isDeprecated" : false,
1940 | "deprecationReason" : null
1941 | }, {
1942 | "name" : "locations",
1943 | "description" : null,
1944 | "args" : [ ],
1945 | "type" : {
1946 | "kind" : "LIST",
1947 | "name" : null,
1948 | "ofType" : {
1949 | "kind" : "NON_NULL",
1950 | "name" : null,
1951 | "ofType" : {
1952 | "kind" : "ENUM",
1953 | "name" : "__DirectiveLocation",
1954 | "ofType" : null
1955 | }
1956 | }
1957 | },
1958 | "isDeprecated" : false,
1959 | "deprecationReason" : null
1960 | }, {
1961 | "name" : "args",
1962 | "description" : null,
1963 | "args" : [ ],
1964 | "type" : {
1965 | "kind" : "NON_NULL",
1966 | "name" : null,
1967 | "ofType" : {
1968 | "kind" : "LIST",
1969 | "name" : null,
1970 | "ofType" : {
1971 | "kind" : "NON_NULL",
1972 | "name" : null,
1973 | "ofType" : {
1974 | "kind" : "OBJECT",
1975 | "name" : "__InputValue",
1976 | "ofType" : null
1977 | }
1978 | }
1979 | }
1980 | },
1981 | "isDeprecated" : false,
1982 | "deprecationReason" : null
1983 | }, {
1984 | "name" : "onOperation",
1985 | "description" : null,
1986 | "args" : [ ],
1987 | "type" : {
1988 | "kind" : "SCALAR",
1989 | "name" : "Boolean",
1990 | "ofType" : null
1991 | },
1992 | "isDeprecated" : true,
1993 | "deprecationReason" : "Use `locations`."
1994 | }, {
1995 | "name" : "onFragment",
1996 | "description" : null,
1997 | "args" : [ ],
1998 | "type" : {
1999 | "kind" : "SCALAR",
2000 | "name" : "Boolean",
2001 | "ofType" : null
2002 | },
2003 | "isDeprecated" : true,
2004 | "deprecationReason" : "Use `locations`."
2005 | }, {
2006 | "name" : "onField",
2007 | "description" : null,
2008 | "args" : [ ],
2009 | "type" : {
2010 | "kind" : "SCALAR",
2011 | "name" : "Boolean",
2012 | "ofType" : null
2013 | },
2014 | "isDeprecated" : true,
2015 | "deprecationReason" : "Use `locations`."
2016 | } ],
2017 | "inputFields" : null,
2018 | "interfaces" : [ ],
2019 | "enumValues" : null,
2020 | "possibleTypes" : null
2021 | }, {
2022 | "kind" : "ENUM",
2023 | "name" : "__DirectiveLocation",
2024 | "description" : "An enum describing valid locations where a directive can be placed",
2025 | "fields" : null,
2026 | "inputFields" : null,
2027 | "interfaces" : null,
2028 | "enumValues" : [ {
2029 | "name" : "QUERY",
2030 | "description" : "Indicates the directive is valid on queries.",
2031 | "isDeprecated" : false,
2032 | "deprecationReason" : null
2033 | }, {
2034 | "name" : "MUTATION",
2035 | "description" : "Indicates the directive is valid on mutations.",
2036 | "isDeprecated" : false,
2037 | "deprecationReason" : null
2038 | }, {
2039 | "name" : "FIELD",
2040 | "description" : "Indicates the directive is valid on fields.",
2041 | "isDeprecated" : false,
2042 | "deprecationReason" : null
2043 | }, {
2044 | "name" : "FRAGMENT_DEFINITION",
2045 | "description" : "Indicates the directive is valid on fragment definitions.",
2046 | "isDeprecated" : false,
2047 | "deprecationReason" : null
2048 | }, {
2049 | "name" : "FRAGMENT_SPREAD",
2050 | "description" : "Indicates the directive is valid on fragment spreads.",
2051 | "isDeprecated" : false,
2052 | "deprecationReason" : null
2053 | }, {
2054 | "name" : "INLINE_FRAGMENT",
2055 | "description" : "Indicates the directive is valid on inline fragments.",
2056 | "isDeprecated" : false,
2057 | "deprecationReason" : null
2058 | }, {
2059 | "name" : "SCHEMA",
2060 | "description" : "Indicates the directive is valid on a schema SDL definition.",
2061 | "isDeprecated" : false,
2062 | "deprecationReason" : null
2063 | }, {
2064 | "name" : "SCALAR",
2065 | "description" : "Indicates the directive is valid on a scalar SDL definition.",
2066 | "isDeprecated" : false,
2067 | "deprecationReason" : null
2068 | }, {
2069 | "name" : "OBJECT",
2070 | "description" : "Indicates the directive is valid on an object SDL definition.",
2071 | "isDeprecated" : false,
2072 | "deprecationReason" : null
2073 | }, {
2074 | "name" : "FIELD_DEFINITION",
2075 | "description" : "Indicates the directive is valid on a field SDL definition.",
2076 | "isDeprecated" : false,
2077 | "deprecationReason" : null
2078 | }, {
2079 | "name" : "ARGUMENT_DEFINITION",
2080 | "description" : "Indicates the directive is valid on a field argument SDL definition.",
2081 | "isDeprecated" : false,
2082 | "deprecationReason" : null
2083 | }, {
2084 | "name" : "INTERFACE",
2085 | "description" : "Indicates the directive is valid on an interface SDL definition.",
2086 | "isDeprecated" : false,
2087 | "deprecationReason" : null
2088 | }, {
2089 | "name" : "UNION",
2090 | "description" : "Indicates the directive is valid on an union SDL definition.",
2091 | "isDeprecated" : false,
2092 | "deprecationReason" : null
2093 | }, {
2094 | "name" : "ENUM",
2095 | "description" : "Indicates the directive is valid on an enum SDL definition.",
2096 | "isDeprecated" : false,
2097 | "deprecationReason" : null
2098 | }, {
2099 | "name" : "ENUM_VALUE",
2100 | "description" : "Indicates the directive is valid on an enum value SDL definition.",
2101 | "isDeprecated" : false,
2102 | "deprecationReason" : null
2103 | }, {
2104 | "name" : "INPUT_OBJECT",
2105 | "description" : "Indicates the directive is valid on an input object SDL definition.",
2106 | "isDeprecated" : false,
2107 | "deprecationReason" : null
2108 | }, {
2109 | "name" : "INPUT_FIELD_DEFINITION",
2110 | "description" : "Indicates the directive is valid on an input object field SDL definition.",
2111 | "isDeprecated" : false,
2112 | "deprecationReason" : null
2113 | } ],
2114 | "possibleTypes" : null
2115 | } ],
2116 | "directives" : [ {
2117 | "name" : "include",
2118 | "description" : "Directs the executor to include this field or fragment only when the `if` argument is true",
2119 | "locations" : [ "FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT" ],
2120 | "args" : [ {
2121 | "name" : "if",
2122 | "description" : "Included when true.",
2123 | "type" : {
2124 | "kind" : "NON_NULL",
2125 | "name" : null,
2126 | "ofType" : {
2127 | "kind" : "SCALAR",
2128 | "name" : "Boolean",
2129 | "ofType" : null
2130 | }
2131 | },
2132 | "defaultValue" : null
2133 | } ],
2134 | "onOperation" : false,
2135 | "onFragment" : true,
2136 | "onField" : true
2137 | }, {
2138 | "name" : "skip",
2139 | "description" : "Directs the executor to skip this field or fragment when the `if`'argument is true.",
2140 | "locations" : [ "FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT" ],
2141 | "args" : [ {
2142 | "name" : "if",
2143 | "description" : "Skipped when true.",
2144 | "type" : {
2145 | "kind" : "NON_NULL",
2146 | "name" : null,
2147 | "ofType" : {
2148 | "kind" : "SCALAR",
2149 | "name" : "Boolean",
2150 | "ofType" : null
2151 | }
2152 | },
2153 | "defaultValue" : null
2154 | } ],
2155 | "onOperation" : false,
2156 | "onFragment" : true,
2157 | "onField" : true
2158 | }, {
2159 | "name" : "defer",
2160 | "description" : "This directive allows results to be deferred during execution",
2161 | "locations" : [ "FIELD" ],
2162 | "args" : [ ],
2163 | "onOperation" : false,
2164 | "onFragment" : false,
2165 | "onField" : true
2166 | }, {
2167 | "name" : "aws_iam",
2168 | "description" : "Tells the service this field/object has access authorized by sigv4 signing.",
2169 | "locations" : [ "OBJECT", "FIELD_DEFINITION" ],
2170 | "args" : [ ],
2171 | "onOperation" : false,
2172 | "onFragment" : false,
2173 | "onField" : false
2174 | }, {
2175 | "name" : "aws_publish",
2176 | "description" : "Tells the service which subscriptions will be published to when this mutation is called. This directive is deprecated use @aws_susbscribe directive instead.",
2177 | "locations" : [ "FIELD_DEFINITION" ],
2178 | "args" : [ {
2179 | "name" : "subscriptions",
2180 | "description" : "List of subscriptions which will be published to when this mutation is called.",
2181 | "type" : {
2182 | "kind" : "LIST",
2183 | "name" : null,
2184 | "ofType" : {
2185 | "kind" : "SCALAR",
2186 | "name" : "String",
2187 | "ofType" : null
2188 | }
2189 | },
2190 | "defaultValue" : null
2191 | } ],
2192 | "onOperation" : false,
2193 | "onFragment" : false,
2194 | "onField" : false
2195 | }, {
2196 | "name" : "aws_subscribe",
2197 | "description" : "Tells the service which mutation triggers this subscription.",
2198 | "locations" : [ "FIELD_DEFINITION" ],
2199 | "args" : [ {
2200 | "name" : "mutations",
2201 | "description" : "List of mutations which will trigger this subscription when they are called.",
2202 | "type" : {
2203 | "kind" : "LIST",
2204 | "name" : null,
2205 | "ofType" : {
2206 | "kind" : "SCALAR",
2207 | "name" : "String",
2208 | "ofType" : null
2209 | }
2210 | },
2211 | "defaultValue" : null
2212 | } ],
2213 | "onOperation" : false,
2214 | "onFragment" : false,
2215 | "onField" : false
2216 | }, {
2217 | "name" : "aws_auth",
2218 | "description" : "Directs the schema to enforce authorization on a field",
2219 | "locations" : [ "FIELD_DEFINITION" ],
2220 | "args" : [ {
2221 | "name" : "cognito_groups",
2222 | "description" : "List of cognito user pool groups which have access on this field",
2223 | "type" : {
2224 | "kind" : "LIST",
2225 | "name" : null,
2226 | "ofType" : {
2227 | "kind" : "SCALAR",
2228 | "name" : "String",
2229 | "ofType" : null
2230 | }
2231 | },
2232 | "defaultValue" : null
2233 | } ],
2234 | "onOperation" : false,
2235 | "onFragment" : false,
2236 | "onField" : false
2237 | }, {
2238 | "name" : "deprecated",
2239 | "description" : null,
2240 | "locations" : [ "FIELD_DEFINITION", "ENUM_VALUE" ],
2241 | "args" : [ {
2242 | "name" : "reason",
2243 | "description" : null,
2244 | "type" : {
2245 | "kind" : "SCALAR",
2246 | "name" : "String",
2247 | "ofType" : null
2248 | },
2249 | "defaultValue" : "\"No longer supported\""
2250 | } ],
2251 | "onOperation" : false,
2252 | "onFragment" : false,
2253 | "onField" : false
2254 | }, {
2255 | "name" : "aws_api_key",
2256 | "description" : "Tells the service this field/object has access authorized by an API key.",
2257 | "locations" : [ "OBJECT", "FIELD_DEFINITION" ],
2258 | "args" : [ ],
2259 | "onOperation" : false,
2260 | "onFragment" : false,
2261 | "onField" : false
2262 | }, {
2263 | "name" : "aws_cognito_user_pools",
2264 | "description" : "Tells the service this field/object has access authorized by a Cognito User Pools token.",
2265 | "locations" : [ "OBJECT", "FIELD_DEFINITION" ],
2266 | "args" : [ {
2267 | "name" : "cognito_groups",
2268 | "description" : "List of cognito user pool groups which have access on this field",
2269 | "type" : {
2270 | "kind" : "LIST",
2271 | "name" : null,
2272 | "ofType" : {
2273 | "kind" : "SCALAR",
2274 | "name" : "String",
2275 | "ofType" : null
2276 | }
2277 | },
2278 | "defaultValue" : null
2279 | } ],
2280 | "onOperation" : false,
2281 | "onFragment" : false,
2282 | "onField" : false
2283 | }, {
2284 | "name" : "aws_oidc",
2285 | "description" : "Tells the service this field/object has access authorized by an OIDC token.",
2286 | "locations" : [ "OBJECT", "FIELD_DEFINITION" ],
2287 | "args" : [ ],
2288 | "onOperation" : false,
2289 | "onFragment" : false,
2290 | "onField" : false
2291 | } ]
2292 | }
2293 | }
2294 | }
--------------------------------------------------------------------------------
/src/graphql/subscriptions.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | // this is an auto generated file. This will be overwritten
3 |
4 | export const onCreateDevice = /* GraphQL */ `
5 | subscription OnCreateDevice {
6 | onCreateDevice {
7 | thingName
8 | username
9 | description
10 | createdAt
11 | updatedAt
12 | }
13 | }
14 | `;
15 | export const onUpdateDevice = /* GraphQL */ `
16 | subscription OnUpdateDevice {
17 | onUpdateDevice {
18 | thingName
19 | username
20 | description
21 | createdAt
22 | updatedAt
23 | }
24 | }
25 | `;
26 | export const onDeleteDevice = /* GraphQL */ `
27 | subscription OnDeleteDevice {
28 | onDeleteDevice {
29 | thingName
30 | username
31 | description
32 | createdAt
33 | updatedAt
34 | }
35 | }
36 | `;
37 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render(, document.getElementById('root'));
8 |
9 | // If you want your app to work offline and load faster, you can change
10 | // unregister() to register() below. Note this comes with some pitfalls.
11 | // Learn more about service workers: https://bit.ly/CRA-PWA
12 | serviceWorker.unregister();
13 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/src/serviceWorker.js:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.1/8 is considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | export function register(config) {
24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
25 | // The URL constructor is available in all browsers that support SW.
26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
27 | if (publicUrl.origin !== window.location.origin) {
28 | // Our service worker won't work if PUBLIC_URL is on a different origin
29 | // from what our page is served on. This might happen if a CDN is used to
30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
31 | return;
32 | }
33 |
34 | window.addEventListener('load', () => {
35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
36 |
37 | if (isLocalhost) {
38 | // This is running on localhost. Let's check if a service worker still exists or not.
39 | checkValidServiceWorker(swUrl, config);
40 |
41 | // Add some additional logging to localhost, pointing developers to the
42 | // service worker/PWA documentation.
43 | navigator.serviceWorker.ready.then(() => {
44 | console.log(
45 | 'This web app is being served cache-first by a service ' +
46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
47 | );
48 | });
49 | } else {
50 | // Is not localhost. Just register service worker
51 | registerValidSW(swUrl, config);
52 | }
53 | });
54 | }
55 | }
56 |
57 | function registerValidSW(swUrl, config) {
58 | navigator.serviceWorker
59 | .register(swUrl)
60 | .then(registration => {
61 | registration.onupdatefound = () => {
62 | const installingWorker = registration.installing;
63 | if (installingWorker == null) {
64 | return;
65 | }
66 | installingWorker.onstatechange = () => {
67 | if (installingWorker.state === 'installed') {
68 | if (navigator.serviceWorker.controller) {
69 | // At this point, the updated precached content has been fetched,
70 | // but the previous service worker will still serve the older
71 | // content until all client tabs are closed.
72 | console.log(
73 | 'New content is available and will be used when all ' +
74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
75 | );
76 |
77 | // Execute callback
78 | if (config && config.onUpdate) {
79 | config.onUpdate(registration);
80 | }
81 | } else {
82 | // At this point, everything has been precached.
83 | // It's the perfect time to display a
84 | // "Content is cached for offline use." message.
85 | console.log('Content is cached for offline use.');
86 |
87 | // Execute callback
88 | if (config && config.onSuccess) {
89 | config.onSuccess(registration);
90 | }
91 | }
92 | }
93 | };
94 | };
95 | })
96 | .catch(error => {
97 | console.error('Error during service worker registration:', error);
98 | });
99 | }
100 |
101 | function checkValidServiceWorker(swUrl, config) {
102 | // Check if the service worker can be found. If it can't reload the page.
103 | fetch(swUrl)
104 | .then(response => {
105 | // Ensure service worker exists, and that we really are getting a JS file.
106 | const contentType = response.headers.get('content-type');
107 | if (
108 | response.status === 404 ||
109 | (contentType != null && contentType.indexOf('javascript') === -1)
110 | ) {
111 | // No service worker found. Probably a different app. Reload the page.
112 | navigator.serviceWorker.ready.then(registration => {
113 | registration.unregister().then(() => {
114 | window.location.reload();
115 | });
116 | });
117 | } else {
118 | // Service worker found. Proceed as normal.
119 | registerValidSW(swUrl, config);
120 | }
121 | })
122 | .catch(() => {
123 | console.log(
124 | 'No internet connection found. App is running in offline mode.'
125 | );
126 | });
127 | }
128 |
129 | export function unregister() {
130 | if ('serviceWorker' in navigator) {
131 | navigator.serviceWorker.ready.then(registration => {
132 | registration.unregister();
133 | });
134 | }
135 | }
136 |
--------------------------------------------------------------------------------