├── example.jpg ├── public ├── robots.txt ├── favicon.ico ├── logo192.png ├── logo512.png ├── manifest.json └── index.html ├── src ├── index.css ├── index.js ├── components │ ├── Dialog.js │ ├── Track-Listing.js │ ├── Markdown-Viewer.js │ ├── Listings.js │ ├── All-Listings.js │ ├── Favorite-Listings.js │ ├── Listing.js │ └── Listing-Editor.js ├── graphql │ ├── queries.js │ ├── mutations.js │ └── schema.json ├── App.js └── serviceWorker.js ├── amplify ├── backend │ ├── api │ │ └── jobassist │ │ │ ├── parameters.json │ │ │ ├── schema.graphql │ │ │ └── stacks │ │ │ └── CustomResources.json │ ├── backend-config.json │ └── auth │ │ └── jobassist8b1be0cb │ │ ├── parameters.json │ │ └── jobassist8b1be0cb-cloudformation-template.yml └── .config │ └── project-config.json ├── .graphqlconfig.yml ├── .gitignore ├── package.json └── README.md /example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkemple/journey/HEAD/example.jpg -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkemple/journey/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkemple/journey/HEAD/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kkemple/journey/HEAD/public/logo512.png -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #152939; 3 | font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; 4 | min-height: 100vh; 5 | } 6 | -------------------------------------------------------------------------------- /amplify/backend/api/jobassist/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "AppSyncApiName": "jobassist", 3 | "DynamoDBBillingMode": "PAY_PER_REQUEST", 4 | "DynamoDBEnableServerSideEncryption": "false", 5 | "AuthCognitoUserPoolId": { 6 | "Fn::GetAtt": [ 7 | "authjobassist8b1be0cb", 8 | "Outputs.UserPoolId" 9 | ] 10 | } 11 | } -------------------------------------------------------------------------------- /.graphqlconfig.yml: -------------------------------------------------------------------------------- 1 | projects: 2 | jobassist: 3 | schemaPath: amplify/backend/api/jobassist/build/schema.graphql 4 | includes: 5 | - src/graphql/**/*.js 6 | excludes: 7 | - ./amplify/** 8 | extensions: 9 | amplify: 10 | codeGenTarget: javascript 11 | generatedFileName: '' 12 | docsFilePath: src/graphql 13 | -------------------------------------------------------------------------------- /amplify/backend/backend-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "auth": { 3 | "jobassist8b1be0cb": { 4 | "service": "Cognito", 5 | "providerPlugin": "awscloudformation", 6 | "dependsOn": [] 7 | } 8 | }, 9 | "api": { 10 | "jobassist": { 11 | "service": "AppSync", 12 | "providerPlugin": "awscloudformation", 13 | "output": { 14 | "securityType": "AMAZON_COGNITO_USER_POOLS" 15 | } 16 | } 17 | } 18 | } -------------------------------------------------------------------------------- /amplify/.config/project-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "job-assist", 3 | "version": "2.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/backend/api/jobassist/schema.graphql: -------------------------------------------------------------------------------- 1 | type Listing @model(subscriptions: null) @auth(rules: [{ allow: owner }]) { 2 | id: ID! 3 | title: String! 4 | company: String! 5 | url: String! 6 | status: Status! 7 | favorite: Boolean! 8 | notes: String 9 | relatedDate: String 10 | contactName: String 11 | contactEmail: String 12 | contactPhoneNumber: String 13 | createdAt: String 14 | updatedAt: String 15 | } 16 | 17 | enum Status { 18 | APPLIED 19 | TRACKING 20 | INTERVIEWING 21 | TAKE_HOME_ASSIGNMENT 22 | } 23 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.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 | 25 | #amplify 26 | amplify/\#current-cloud-backend 27 | amplify/.config/local-* 28 | amplify/mock-data 29 | amplify/backend/amplify-meta.json 30 | amplify/backend/awscloudformation 31 | build/ 32 | dist/ 33 | node_modules/ 34 | aws-exports.js 35 | awsconfiguration.json -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import App from "./App"; 4 | import * as serviceWorker from "./serviceWorker"; 5 | import Amplify from "aws-amplify"; 6 | import "normalize.css/normalize.css"; 7 | 8 | import "./index.css"; 9 | import amplifyConfig from "./aws-exports"; 10 | 11 | Amplify.configure(amplifyConfig); 12 | 13 | ReactDOM.render(, document.getElementById("root")); 14 | 15 | // If you want your app to work offline and load faster, you can change 16 | // unregister() to register() below. Note this comes with some pitfalls. 17 | // Learn more about service workers: https://bit.ly/CRA-PWA 18 | serviceWorker.unregister(); 19 | -------------------------------------------------------------------------------- /src/components/Dialog.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Dialog, DialogOverlay, DialogContent } from "@reach/dialog"; 3 | import styled from "@emotion/styled"; 4 | 5 | const StyledDialogOverlay = styled(DialogOverlay)` 6 | position: fixed; 7 | top: 0; 8 | bottom: 0; 9 | left: 0; 10 | right: 0; 11 | background-color: hsla(207, 46%, 15%, 0.95); 12 | padding: 24px; 13 | z-index: 99; 14 | `; 15 | 16 | const StyledDialogContent = styled(DialogContent)` 17 | background-color: #31465f; 18 | border-radius: 4px; 19 | max-width: 800px; 20 | box-shadow: 0 0 9px rgba(0, 0, 0, 0.3); 21 | padding: 24px; 22 | margin: 24px auto; 23 | `; 24 | 25 | export default props => ( 26 | 27 | 28 | {props.children} 29 | 30 | 31 | ); 32 | -------------------------------------------------------------------------------- /src/graphql/queries.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // this is an auto generated file. This will be overwritten 3 | 4 | export const getListing = `query GetListing($id: ID!) { 5 | getListing(id: $id) { 6 | id 7 | title 8 | company 9 | url 10 | status 11 | favorite 12 | notes 13 | relatedDate 14 | contactName 15 | contactEmail 16 | contactPhoneNumber 17 | createdAt 18 | updatedAt 19 | } 20 | } 21 | `; 22 | export const listListings = `query ListListings( 23 | $filter: ModelListingFilterInput 24 | $limit: Int 25 | $nextToken: String 26 | ) { 27 | listListings(filter: $filter, limit: $limit, nextToken: $nextToken) { 28 | items { 29 | id 30 | title 31 | company 32 | url 33 | status 34 | favorite 35 | notes 36 | relatedDate 37 | contactName 38 | contactEmail 39 | contactPhoneNumber 40 | createdAt 41 | updatedAt 42 | } 43 | nextToken 44 | } 45 | } 46 | `; 47 | -------------------------------------------------------------------------------- /src/components/Track-Listing.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import styled from "@emotion/styled"; 3 | import { Button } from "@rebass/emotion"; 4 | 5 | import ListingEditor from "./Listing-Editor"; 6 | 7 | const TrackListingContainer = styled("div")` 8 | text-align: right; 9 | `; 10 | 11 | const StyledButton = styled(Button)` 12 | background-color: #ffac31; 13 | cursor: pointer; 14 | `; 15 | 16 | export default props => { 17 | const [showDialog, setShowDialog] = useState(false); 18 | return ( 19 | <> 20 | 21 | { 23 | setShowDialog(true); 24 | }} 25 | > 26 | Track Listing 27 | 28 | 29 | {showDialog && ( 30 | { 33 | setShowDialog(false); 34 | }} 35 | /> 36 | )} 37 | 38 | ); 39 | }; 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "job-assist", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@emotion/core": "^10.0.16", 7 | "@emotion/styled": "^10.0.15", 8 | "@reach/dialog": "^0.2.9", 9 | "@reach/tabs": "^0.1.6", 10 | "@rebass/emotion": "^3.2.0", 11 | "@rebass/forms": "^4.0.5", 12 | "aws-amplify": "^1.1.36", 13 | "aws-amplify-react": "^2.3.12", 14 | "formik": "^1.5.8", 15 | "normalize.css": "^8.0.1", 16 | "react": "^16.9.0", 17 | "react-dom": "^16.9.0", 18 | "react-icons": "^3.7.0", 19 | "react-markdown": "^4.1.0", 20 | "react-scripts": "3.1.1", 21 | "react-syntax-highlighter": "^11.0.2" 22 | }, 23 | "scripts": { 24 | "start": "react-scripts start", 25 | "build": "react-scripts build", 26 | "test": "react-scripts test", 27 | "eject": "react-scripts eject" 28 | }, 29 | "eslintConfig": { 30 | "extends": "react-app" 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 | } 45 | -------------------------------------------------------------------------------- /src/graphql/mutations.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // this is an auto generated file. This will be overwritten 3 | 4 | export const createListing = `mutation CreateListing($input: CreateListingInput!) { 5 | createListing(input: $input) { 6 | id 7 | title 8 | company 9 | url 10 | status 11 | favorite 12 | notes 13 | relatedDate 14 | contactName 15 | contactEmail 16 | contactPhoneNumber 17 | createdAt 18 | updatedAt 19 | } 20 | } 21 | `; 22 | export const updateListing = `mutation UpdateListing($input: UpdateListingInput!) { 23 | updateListing(input: $input) { 24 | id 25 | title 26 | company 27 | url 28 | status 29 | favorite 30 | notes 31 | relatedDate 32 | contactName 33 | contactEmail 34 | contactPhoneNumber 35 | createdAt 36 | updatedAt 37 | } 38 | } 39 | `; 40 | export const deleteListing = `mutation DeleteListing($input: DeleteListingInput!) { 41 | deleteListing(input: $input) { 42 | id 43 | title 44 | company 45 | url 46 | status 47 | favorite 48 | notes 49 | relatedDate 50 | contactName 51 | contactEmail 52 | contactPhoneNumber 53 | createdAt 54 | updatedAt 55 | } 56 | } 57 | `; 58 | -------------------------------------------------------------------------------- /src/components/Markdown-Viewer.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactMarkdown from "react-markdown"; 3 | import { Prism } from "react-syntax-highlighter"; 4 | import styled from "@emotion/styled"; 5 | import { Button } from "@rebass/emotion"; 6 | 7 | import Dialog from "./Dialog"; 8 | 9 | const StyledButton = styled(Button)` 10 | background-color: #ffac31; 11 | `; 12 | 13 | const DismissContainer = styled("div")` 14 | display: flex; 15 | justify-content: flex-end; 16 | margin-bottom: 8px; 17 | `; 18 | 19 | const StyledMarkdown = styled(ReactMarkdown)` 20 | color: #ffffff; 21 | max-height: 550px; 22 | overflow: scroll; 23 | padding: 8px; 24 | 25 | @media (max-height: 570px) { 26 | max-height: 350px; 27 | } 28 | 29 | @media (max-height: 675px) { 30 | max-height: 450px; 31 | } 32 | 33 | pre { 34 | border-radius: 4px; 35 | } 36 | `; 37 | 38 | const CodeBlock = props => ( 39 | {props.value} 40 | ); 41 | 42 | export default props => ( 43 | 44 | 45 | Close 46 | 47 | 51 | 52 | ); 53 | -------------------------------------------------------------------------------- /amplify/backend/api/jobassist/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/auth/jobassist8b1be0cb/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "identityPoolName": "jobassist8b1be0cb_identitypool_8b1be0cb", 3 | "allowUnauthenticatedIdentities": false, 4 | "resourceNameTruncated": "jobass8b1be0cb", 5 | "userPoolName": "jobassist8b1be0cb_userpool_8b1be0cb", 6 | "autoVerifiedAttributes": [ 7 | "email" 8 | ], 9 | "mfaConfiguration": "OFF", 10 | "mfaTypes": [ 11 | "SMS Text Message" 12 | ], 13 | "smsAuthenticationMessage": "Your authentication code is {####}", 14 | "smsVerificationMessage": "Your verification code is {####}", 15 | "emailVerificationSubject": "Your verification code", 16 | "emailVerificationMessage": "Your verification code is {####}", 17 | "defaultPasswordPolicy": false, 18 | "passwordPolicyMinLength": 8, 19 | "passwordPolicyCharacters": [], 20 | "requiredAttributes": [ 21 | "email" 22 | ], 23 | "userpoolClientGenerateSecret": true, 24 | "userpoolClientRefreshTokenValidity": 30, 25 | "userpoolClientWriteAttributes": [ 26 | "email" 27 | ], 28 | "userpoolClientReadAttributes": [ 29 | "email" 30 | ], 31 | "userpoolClientLambdaRole": "jobass8b1be0cb_userpoolclient_lambda_role", 32 | "userpoolClientSetAttributes": false, 33 | "resourceName": "jobassist8b1be0cb", 34 | "authSelections": "identityPoolAndUserPool", 35 | "authRoleArn": { 36 | "Fn::GetAtt": [ 37 | "AuthRole", 38 | "Arn" 39 | ] 40 | }, 41 | "unauthRoleArn": { 42 | "Fn::GetAtt": [ 43 | "UnauthRole", 44 | "Arn" 45 | ] 46 | }, 47 | "useDefault": "default", 48 | "dependsOn": [] 49 | } -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { Auth } from "aws-amplify"; 3 | import { Authenticator, Greetings, SignUp } from "aws-amplify-react"; 4 | import styled from "@emotion/styled"; 5 | 6 | import awsExports from "./aws-exports"; 7 | import Listings from "./components/Listings"; 8 | 9 | const Title = styled("h1")` 10 | text-align: center; 11 | text-transform: uppercase; 12 | color: #ffffff; 13 | `; 14 | 15 | const theme = { 16 | formContainer: { 17 | margin: 0, 18 | padding: "24px" 19 | }, 20 | formSection: { 21 | backgroundColor: "#31465f", 22 | borderRadius: "4px" 23 | }, 24 | sectionHeader: { 25 | color: "#ffffff" 26 | }, 27 | inputLabel: { 28 | color: "#ffffff" 29 | }, 30 | input: { 31 | backgroundColor: "#152939", 32 | color: "#FFAC31" 33 | }, 34 | hint: { 35 | color: "#ffffff" 36 | }, 37 | button: { 38 | borderRadius: "3px", 39 | backgroundColor: "#FFAC31" 40 | }, 41 | a: { 42 | color: "#FFAC31" 43 | } 44 | }; 45 | 46 | function App() { 47 | const [state, setState] = useState({ isLoggedIn: false, user: null }); 48 | 49 | const checkLoggedIn = () => { 50 | Auth.currentAuthenticatedUser() 51 | .then(data => { 52 | const user = { username: data.username, ...data.attributes }; 53 | setState({ isLoggedIn: true, user }); 54 | }) 55 | .catch(error => console.log(error)); 56 | }; 57 | 58 | useEffect(() => { 59 | checkLoggedIn(); 60 | }, []); 61 | 62 | return state.isLoggedIn ? ( 63 | 64 | ) : ( 65 | <> 66 | Journey 67 | { 69 | if (authState === "signedIn") { 70 | checkLoggedIn(); 71 | } 72 | }} 73 | amplifyConfig={awsExports} 74 | hide={[Greetings, SignUp]} 75 | theme={theme} 76 | /> 77 | 78 | ); 79 | } 80 | 81 | export default App; 82 | -------------------------------------------------------------------------------- /src/components/Listings.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import styled from "@emotion/styled"; 3 | import { Auth } from "aws-amplify"; 4 | import { Button } from "@rebass/emotion"; 5 | import { Tabs, TabList, Tab, TabPanels, TabPanel } from "@reach/tabs"; 6 | 7 | import AllListings from "./All-Listings"; 8 | import FavoriteListings from "./Favorite-Listings"; 9 | 10 | const Header = styled("div")` 11 | background-color: #31465f; 12 | padding-left: 16px; 13 | padding-right: 16px; 14 | display: flex; 15 | justify-content: space-between; 16 | align-items: center; 17 | position: fixed; 18 | right: 0; 19 | left: 0; 20 | height: 80px; 21 | z-index: 2; 22 | `; 23 | 24 | const Title = styled("h1")` 25 | margin-top: 0; 26 | margin-bottom: 0; 27 | text-transform: uppercase; 28 | color: #ffffff; 29 | `; 30 | 31 | const SignOutButton = styled(Button)` 32 | background-color: #ffac31; 33 | cursor: pointer; 34 | `; 35 | 36 | const StyledTabs = styled(Tabs)` 37 | padding-top: 80px; 38 | `; 39 | 40 | const StyledTabList = styled(TabList)` 41 | display: flex; 42 | justify-content: stretch; 43 | align-items: center; 44 | position: fixed; 45 | top: 80px; 46 | left: 0; 47 | right: 0; 48 | height; 40px; 49 | box-shadow: 0 3px 6px rgba(0,0,0,0.3); 50 | 51 | & > [data-selected] { 52 | border-bottom-color: #FFAC31; 53 | color: #FFAC31; 54 | } 55 | `; 56 | 57 | const StyledTabPanels = styled(TabPanels)` 58 | padding-top: 60px; 59 | display: flex; 60 | justify-content: stretch; 61 | `; 62 | 63 | const StyledTabPanel = styled(TabPanel)` 64 | flex: 1; 65 | padding: 16px; 66 | `; 67 | 68 | const StyledTab = styled(Tab)` 69 | text-transform: uppercase; 70 | flex: 1; 71 | padding: 16px; 72 | color: #ffffff; 73 | background-color: #31465f; 74 | font-size: 16px; 75 | border: none; 76 | border-bottom: 3px solid #31465f; 77 | `; 78 | 79 | export default () => { 80 | const [tabIndex, setTabIndex] = useState(0); 81 | 82 | return ( 83 | <> 84 |
85 | Journey 86 | { 88 | Auth.signOut().then(() => window.location.reload()); 89 | }} 90 | > 91 | Sign Out 92 | 93 |
94 | setTabIndex(index)}> 95 | 96 | All Listings 97 | Favorites 98 | 99 | 100 | {tabIndex === 0 && } 101 | 102 | {tabIndex === 1 && } 103 | 104 | 105 | 106 | 107 | ); 108 | }; 109 | -------------------------------------------------------------------------------- /src/components/All-Listings.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import { API, graphqlOperation } from "aws-amplify"; 3 | import styled from "@emotion/styled"; 4 | 5 | import Listing from "./Listing"; 6 | import TrackListing from "./Track-Listing"; 7 | import { listListings } from "../graphql/queries"; 8 | import { 9 | createListing, 10 | deleteListing, 11 | updateListing 12 | } from "../graphql/mutations"; 13 | 14 | const Container = styled("div")` 15 | max-width: 800px; 16 | margin: 16px auto; 17 | `; 18 | 19 | const Listings = styled("div")` 20 | margin-top: 24px; 21 | `; 22 | 23 | export default () => { 24 | const [listings, setListings] = useState([]); 25 | 26 | useEffect(() => { 27 | API.graphql(graphqlOperation(listListings)) 28 | .then(result => { 29 | setListings( 30 | result.data.listListings.items.sort((a, b) => { 31 | if (a.updatedAt > b.updatedAt) return -1; 32 | else return 1; 33 | }) 34 | ); 35 | }) 36 | .catch(error => { 37 | console.log(error); 38 | }); 39 | }, []); 40 | 41 | return ( 42 | 43 | { 45 | API.graphql( 46 | graphqlOperation(createListing, { 47 | input: values 48 | }) 49 | ).then(result => { 50 | setListings([result.data.createListing, ...listings]); 51 | }); 52 | }} 53 | /> 54 | 55 | {listings.map(listing => ( 56 | { 60 | API.graphql( 61 | graphqlOperation(updateListing, { 62 | input: { 63 | ...listing, 64 | ...values 65 | } 66 | }) 67 | ).then(result => { 68 | const updatedListings = listings.map(l => { 69 | if (l.id === result.data.updateListing.id) { 70 | return result.data.updateListing; 71 | } 72 | 73 | return l; 74 | }); 75 | 76 | setListings(updatedListings); 77 | }); 78 | }} 79 | onFavorite={() => { 80 | API.graphql( 81 | graphqlOperation(updateListing, { 82 | input: { 83 | ...listing, 84 | favorite: !listing.favorite 85 | } 86 | }) 87 | ).then(result => { 88 | const updatedListings = listings.map(l => { 89 | if (l.id === result.data.updateListing.id) { 90 | return result.data.updateListing; 91 | } 92 | 93 | return l; 94 | }); 95 | 96 | setListings(updatedListings); 97 | }); 98 | }} 99 | onDelete={() => { 100 | if (window.confirm("Are you sure want to delete this listing?")) { 101 | API.graphql( 102 | graphqlOperation(deleteListing, { 103 | input: { id: listing.id } 104 | }) 105 | ).then(result => { 106 | const updatedListings = listings.filter( 107 | l => l.id !== result.data.deleteListing.id 108 | ); 109 | 110 | setListings(updatedListings); 111 | }); 112 | } 113 | }} 114 | /> 115 | ))} 116 | 117 | 118 | ); 119 | }; 120 | -------------------------------------------------------------------------------- /src/components/Favorite-Listings.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from "react"; 2 | import { API, graphqlOperation } from "aws-amplify"; 3 | import styled from "@emotion/styled"; 4 | 5 | import Listing from "./Listing"; 6 | import TrackListing from "./Track-Listing"; 7 | import { listListings } from "../graphql/queries"; 8 | import { 9 | createListing, 10 | deleteListing, 11 | updateListing 12 | } from "../graphql/mutations"; 13 | 14 | const Container = styled("div")` 15 | max-width: 800px; 16 | margin: 16px auto; 17 | `; 18 | 19 | const Listings = styled("div")` 20 | margin-top: 24px; 21 | `; 22 | 23 | export default props => { 24 | const [listings, setListings] = useState([]); 25 | 26 | useEffect(() => { 27 | API.graphql( 28 | graphqlOperation(listListings, { 29 | filter: { 30 | favorite: { 31 | eq: true 32 | } 33 | } 34 | }) 35 | ) 36 | .then(result => { 37 | setListings( 38 | result.data.listListings.items.sort((a, b) => { 39 | if (a.updatedAt > b.updatedAt) return -1; 40 | else return 1; 41 | }) 42 | ); 43 | }) 44 | .catch(error => { 45 | console.log(error); 46 | }); 47 | }, []); 48 | 49 | return ( 50 | 51 | { 53 | API.graphql( 54 | graphqlOperation(createListing, { 55 | input: values 56 | }) 57 | ).then(result => { 58 | if (values.favorite) { 59 | setListings([result.data.createListing, ...listings]); 60 | } 61 | }); 62 | }} 63 | /> 64 | 65 | {listings.map(listing => ( 66 | { 70 | API.graphql( 71 | graphqlOperation(updateListing, { 72 | input: { 73 | ...listing, 74 | ...values 75 | } 76 | }) 77 | ).then(result => { 78 | if (!result.data.updateListing.favorite) { 79 | setListings( 80 | listings.filter(l => l.id !== result.data.updateListing.id) 81 | ); 82 | return; 83 | } 84 | 85 | const updatedListings = listings.map(l => { 86 | if (l.id === listing.id) { 87 | return result.data.updateListing; 88 | } 89 | 90 | return l; 91 | }); 92 | 93 | setListings(updatedListings); 94 | }); 95 | }} 96 | onFavorite={() => { 97 | API.graphql( 98 | graphqlOperation(updateListing, { 99 | input: { 100 | ...listing, 101 | favorite: !listing.favorite 102 | } 103 | }) 104 | ).then(result => { 105 | if (!result.data.updateListing.favorite) { 106 | setListings( 107 | listings.filter(l => l.id !== result.data.updateListing.id) 108 | ); 109 | return; 110 | } 111 | 112 | const updatedListings = listings.map(l => { 113 | if (l.id === listing.id) { 114 | return result.data.updateListing; 115 | } 116 | 117 | return l; 118 | }); 119 | 120 | setListings(updatedListings); 121 | }); 122 | }} 123 | onDelete={() => { 124 | if (window.confirm("Are you sure want to delete this listing?")) { 125 | API.graphql( 126 | graphqlOperation(deleteListing, { 127 | input: { id: listing.id } 128 | }) 129 | ).then(() => { 130 | const updatedListings = listings.filter( 131 | l => l.id !== listing.id 132 | ); 133 | 134 | setListings(updatedListings); 135 | }); 136 | } 137 | }} 138 | /> 139 | ))} 140 | 141 | 142 | ); 143 | }; 144 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Journey - The Job Listing Tracker 2 | 3 | #### Deploy a full stack web app to help you organize your job search. 4 | 5 | 🛠 Built with React, GraphQL, AWS Amplify, & AWS AppSync 6 | 7 | ### Features 8 | 9 | - 📝 Keep notes in Markdown 10 | - ❤️ Add favorites 11 | - 👮‍ Authenticated 12 | - 🔥 Serverless back end 13 | - 🚀 GraphQL 14 | - 💻 Deploy back end in minutes 15 | 16 | ![](./example.jpg) 17 | 18 | ## Deploy the App 19 | 20 | The app can be configured to be used by only one person, or allow anyone to sign up and use the app. Make sure to pay attention to the instructions as some things are slightly different for a shared app. 21 | 22 | > A shared instance is a great option if you are part of a bootcamp or want to enable others to use this app in their job search. 23 | 24 | ### Deploy the back end and run the app 25 | 26 | 1. Clone the repo & install the dependencies 27 | 28 | ```sh 29 | ~ git clone https://github.com/kkemple/journey.git 30 | ~ cd journey 31 | ~ npm install 32 | ``` 33 | 34 | 2. Initialize and deploy the Amplify project 35 | 36 | ```sh 37 | ~ amplify init 38 | ? Enter a name for the environment: dev (or whatever you would like to call this env) 39 | ? Choose your default editor: 40 | ? Do you want to use an AWS profile? Y 41 | ~ amplify push 42 | ? Are you sure you want to continue? Y 43 | ? Do you want to generate code for your newly created GraphQL API? N 44 | > We already have the GraphQL code generated for this project, so generating it here is not necessary. 45 | ``` 46 | 47 | 3. Add a user for you to log in with (if you plan to host for multiple users and allow registration, skip this step) 48 | 49 | ```sh 50 | ~ amplify auth console 51 | 52 | > choose user pool 53 | ``` 54 | 55 | Under the "Users and Groups" tab, click "Create user". Uncheck the "send an invitation to this new user?" checkbox and enter the necessary attributes, then click "Create user". 56 | 57 | 4. Start the app and login 58 | 59 | ```sh 60 | ~ yarn start 61 | ``` 62 | 63 | Once the app starts enter the username and password you used in the previous step. You will be prompted to change your password. 64 | 65 | ### Deploy the front end 66 | 67 | 1. Create a new repository with your git service of choice 68 | 69 | 2. Push the project to your new repository 70 | 71 | ```sh 72 | ~ git remote add origin 73 | ~ git push --set-upstream master 74 | ``` 75 | 76 | 3. Connect to [AWS Amplify Console](https://console.aws.amazon.com/amplify/home) and wait for build to start. You will be given a production URL and you are ready to track your job listings! 77 | > If you wish to allow users to sign up and use this app then pick the `shared` branch to connect in Amplify Console, otherwise use `master`. 78 | 79 | --- 80 | 81 | ## Create React App Instructions 82 | 83 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 84 | 85 | ## Available Scripts 86 | 87 | In the project directory, you can run: 88 | 89 | ### `npm start` 90 | 91 | Runs the app in the development mode.
92 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 93 | 94 | The page will reload if you make edits.
95 | You will also see any lint errors in the console. 96 | 97 | ### `npm test` 98 | 99 | Launches the test runner in the interactive watch mode.
100 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 101 | 102 | ### `npm run build` 103 | 104 | Builds the app for production to the `build` folder.
105 | It correctly bundles React in production mode and optimizes the build for the best performance. 106 | 107 | The build is minified and the filenames include the hashes.
108 | Your app is ready to be deployed! 109 | 110 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 111 | 112 | ### `npm run eject` 113 | 114 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 115 | 116 | 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. 117 | 118 | 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. 119 | 120 | 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. 121 | 122 | ## Learn More 123 | 124 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 125 | 126 | To learn React, check out the [React documentation](https://reactjs.org/). 127 | 128 | ### Code Splitting 129 | 130 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 131 | 132 | ### Analyzing the Bundle Size 133 | 134 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 135 | 136 | ### Making a Progressive Web App 137 | 138 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 139 | 140 | ### Advanced Configuration 141 | 142 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 143 | 144 | ### Deployment 145 | 146 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 147 | 148 | ### `npm run build` fails to minify 149 | 150 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 151 | -------------------------------------------------------------------------------- /src/components/Listing.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import styled from "@emotion/styled"; 3 | import { 4 | FaRegEdit, 5 | FaRegHeart, 6 | FaHeart, 7 | FaRegStickyNote, 8 | FaExternalLinkAlt, 9 | FaRegTrashAlt, 10 | FaRegAddressBook, 11 | FaRegEnvelope, 12 | FaPhone 13 | } from "react-icons/fa"; 14 | 15 | import ListingEditor from "./Listing-Editor"; 16 | import MarkdownViewer from "./Markdown-Viewer"; 17 | 18 | const Listing = styled("div")` 19 | background-color: #31465f; 20 | border-radius: 4px; 21 | margin-bottom: 24px; 22 | display: flex; 23 | flex-direction: column; 24 | justify-content: space-between; 25 | align-items: stretch; 26 | overflow: hidden; 27 | `; 28 | 29 | const JobTitle = styled("h2")` 30 | color: #ffffff; 31 | margin-top: 0; 32 | margin-bottom: 0; 33 | `; 34 | 35 | const Company = styled("h3")` 36 | color: #ffac31; 37 | margin-top: 0; 38 | margin-bottom: 24px; 39 | `; 40 | 41 | const Icon = styled("button")` 42 | padding: 8px 10px; 43 | display: inline-flex; 44 | justify-content: center; 45 | align-items: center; 46 | color: #ffffff; 47 | border: none; 48 | cursor: pointer; 49 | flex: 1; 50 | background-color: #55667d; 51 | 52 | &:hover { 53 | background-color: #31465f; 54 | } 55 | `; 56 | 57 | const StatusContainer = styled("div")` 58 | min-width: 200px; 59 | display: flex; 60 | justify-content: flex-end; 61 | margin-bottom: auto; 62 | 63 | @media (max-width: 800px) { 64 | justify-content: flex-start; 65 | } 66 | `; 67 | 68 | const Status = styled("div")` 69 | background-color: #55667d; 70 | padding: 6px 12px; 71 | color: #ffac31; 72 | border-radius: 3px; 73 | font-size: 12px; 74 | display: inline; 75 | margin-bottom: 4px; 76 | font-weight: bold; 77 | `; 78 | 79 | const DueDate = styled("span")` 80 | color: #ffac31; 81 | text-transform: uppercase; 82 | font-size: 12px; 83 | display: block; 84 | `; 85 | 86 | const ListingInfo = styled("div")``; 87 | 88 | const ListingMetaData = styled("div")` 89 | display: flex; 90 | justify-content: space-between; 91 | align-items: flex-start; 92 | padding: 24px; 93 | 94 | @media (max-width: 800px) { 95 | flex-direction: column; 96 | justify-content: flex-start; 97 | } 98 | `; 99 | 100 | const ListingContact = styled("div")` 101 | display: flex; 102 | justify-content: space-around; 103 | align-items: center; 104 | padding: 16px; 105 | `; 106 | 107 | const ContactDetail = styled("span")` 108 | color: #ffac31; 109 | margin: 0; 110 | display: flex; 111 | flex-direction: column; 112 | justify-content: center; 113 | align-items: center; 114 | `; 115 | 116 | const Divider = styled("div")` 117 | height: 1px; 118 | background-color: #152939; 119 | `; 120 | 121 | const ListingActions = styled("div")` 122 | display: flex; 123 | justify-content: stretch; 124 | align-items: stretch; 125 | height: 50px; 126 | background-color: #55667d; 127 | `; 128 | 129 | const ExternalLink = styled("a")` 130 | color: #ffffff; 131 | flex: 1; 132 | `; 133 | 134 | const STATUSES = { 135 | TRACKING: "Tracking", 136 | APPLIED: "Applied", 137 | TAKE_HOME_ASSIGNMENT: "Take Home Assignment", 138 | INTERVIEWING: "Interviewing" 139 | }; 140 | 141 | const hasContactInfo = listing => 142 | !!(listing.contactName || listing.contactEmail || listing.contactPhoneNumber); 143 | 144 | export default props => { 145 | const [showEditor, setShowEditor] = useState(false); 146 | const [showMarkdown, setShowMarkdown] = useState(false); 147 | 148 | return ( 149 | 150 | 151 | 152 |
153 | {props.listing.title} 154 | {props.listing.company} 155 |
156 | 157 | 158 | {`Status: ${STATUSES[props.listing.status]}`} 159 | {props.listing.relatedDate && ( 160 | {`Date: ${props.listing.relatedDate}`} 161 | )} 162 | 163 | 164 |
165 | {hasContactInfo(props.listing) && ( 166 | <> 167 | 168 | 169 | 170 | 171 | {props.listing.contactName} 172 | 173 | 174 | 175 | {props.listing.contactEmail} 176 | 177 | 178 | 179 | {props.listing.contactPhoneNumber} 180 | 181 | 182 | 183 | )} 184 |
185 | 186 | 187 | 188 | {props.listing.favorite ? : } 189 | 190 | 191 | 192 | 193 | 194 | 195 | setShowMarkdown(true)}> 196 | 197 | 198 | setShowEditor(true)}> 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | {showEditor && ( 207 | { 210 | setShowEditor(false); 211 | }} 212 | onSave={props.onSaveChanges} 213 | /> 214 | )} 215 | 216 | {showMarkdown && ( 217 | { 220 | setShowMarkdown(false); 221 | }} 222 | /> 223 | )} 224 |
225 | ); 226 | }; 227 | -------------------------------------------------------------------------------- /src/components/Listing-Editor.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import styled from "@emotion/styled"; 3 | import { Button } from "@rebass/emotion"; 4 | import { Label, Select, Input, Checkbox } from "@rebass/forms"; 5 | import { Formik } from "formik"; 6 | import { API, graphqlOperation } from "aws-amplify"; 7 | 8 | import Dialog from "./Dialog"; 9 | import { createListing, updateListing } from "../graphql/mutations"; 10 | 11 | const StyledButton = styled(Button)` 12 | background-color: #ffac31; 13 | cursor: pointer; 14 | `; 15 | 16 | const StyledLabel = styled(Label)` 17 | color: #ffac31; 18 | margin-bottom: 4px; 19 | `; 20 | 21 | const StyledInput = styled(Input)` 22 | color: #ffac31; 23 | border-radius: 3px; 24 | background-color: #152939; 25 | `; 26 | 27 | const StyledSelect = styled(Select)` 28 | color: #ffac31; 29 | border-radius: 3px; 30 | background-color: #152939; 31 | `; 32 | 33 | const StyledTextarea = styled("textarea")` 34 | color: #ffac31; 35 | background-color: #152939; 36 | width: 100%; 37 | min-height: 80px; 38 | border-radius: 3px; 39 | resize: vertical; 40 | `; 41 | 42 | const StyledCheckbox = styled(Checkbox)` 43 | color: #ffac31; 44 | width: auto; 45 | `; 46 | 47 | const CheckboxText = styled("span")` 48 | margin-top: 3px; 49 | `; 50 | 51 | const Divider = styled("div")` 52 | height: 1px; 53 | background-color: #152939; 54 | margin-top: 16px; 55 | margin-bottom: 16px; 56 | `; 57 | 58 | const FormInputs = styled("div")` 59 | max-height: 450px; 60 | overflow: scroll; 61 | border: 1px solid #152939; 62 | padding: 16px; 63 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3); 64 | 65 | @media (max-height: 570px) { 66 | max-height: 300px; 67 | } 68 | 69 | @media (max-height: 675px) { 70 | max-height: 350px; 71 | } 72 | `; 73 | 74 | const Actions = styled("div")` 75 | display: flex; 76 | justify-content: flex-end; 77 | align-items: center; 78 | margin-top: 24px; 79 | `; 80 | 81 | const Message = styled(`span`)` 82 | font-size: 12px; 83 | text-transform: uppercase; 84 | color: #cd3333; 85 | `; 86 | 87 | const InputContainer = styled("div")` 88 | margin-bottom: 16px; 89 | `; 90 | 91 | const Title = styled("h2")` 92 | color: #ffac31; 93 | `; 94 | 95 | const STATUSES = [ 96 | { 97 | display: "Tracking", 98 | value: "TRACKING" 99 | }, 100 | { 101 | display: "Applied", 102 | value: "APPLIED" 103 | }, 104 | { 105 | display: "Take Home Assignment", 106 | value: "TAKE_HOME_ASSIGNMENTS" 107 | }, 108 | { 109 | display: "Interview Set", 110 | value: "INTERVIEWING" 111 | } 112 | ]; 113 | 114 | export default props => ( 115 | 116 | {props.listing ? "Edit Job Listing" : "Track Job Listing"} 117 | { 131 | let errors = {}; 132 | if (!values.title) { 133 | errors.title = "Required"; 134 | } 135 | 136 | if (!values.company) { 137 | errors.company = "Required"; 138 | } 139 | if (!values.url) { 140 | errors.url = "Required"; 141 | } else if ( 142 | !/^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/.test( 143 | values.url 144 | ) 145 | ) { 146 | errors.url = "Invalid URL"; 147 | } 148 | 149 | if ( 150 | values.contactEmail && 151 | !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.contactEmail) 152 | ) { 153 | errors.contactEmail = "Invalid email address"; 154 | } 155 | 156 | return errors; 157 | }} 158 | onSubmit={(values, { setSubmitting, resetForm }) => { 159 | props.onSave(values); 160 | setSubmitting(false); 161 | resetForm(); 162 | props.onDismiss(); 163 | }} 164 | > 165 | {({ 166 | values, 167 | errors, 168 | touched, 169 | handleChange, 170 | handleBlur, 171 | handleSubmit, 172 | isSubmitting 173 | }) => ( 174 |
175 | 176 | 177 | Job Title 178 | 185 | {touched.title && errors.title} 186 | 187 | 188 | 189 | Company 190 | 197 | {touched.company && errors.company} 198 | 199 | 200 | 201 | URL 202 | 209 | {touched.url && errors.url} 210 | 211 | 212 | 213 | Status 214 | 221 | {STATUSES.map(status => ( 222 | 225 | ))} 226 | 227 | 228 | 229 | {values.status && 230 | (values.status === "TAKE_HOME_ASSIGNMENT" || 231 | values.status === "INTERVIEWING") && ( 232 | 233 | 237 | Date 238 | 239 | 246 | 247 | )} 248 | 249 | 250 | 251 | {" "} 257 | Favorite 258 | 259 | 260 | 261 | 262 | Notes 263 | 269 | 270 | 271 | 272 | 273 | 274 | Contact Name 275 | 282 | 283 | 284 | 285 | Contact Email 286 | 293 | {touched.contactEmail && errors.contactEmail} 294 | 295 | 296 | 297 | 298 | Contact Phone Number 299 | 300 | 307 | 308 | 309 | 310 | { 312 | props.onDismiss(); 313 | }} 314 | style={{ marginRight: "8px" }} 315 | > 316 | Cancel 317 | 318 | 319 | {isSubmitting ? "Saving..." : "Save"} 320 | 321 | 322 |
323 | )} 324 |
325 |
326 | ); 327 | -------------------------------------------------------------------------------- /amplify/backend/auth/jobassist8b1be0cb/jobassist8b1be0cb-cloudformation-template.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | 3 | Parameters: 4 | env: 5 | Type: String 6 | authRoleArn: 7 | Type: String 8 | unauthRoleArn: 9 | Type: String 10 | 11 | 12 | 13 | 14 | identityPoolName: 15 | Type: String 16 | 17 | allowUnauthenticatedIdentities: 18 | Type: String 19 | 20 | resourceNameTruncated: 21 | Type: String 22 | 23 | userPoolName: 24 | Type: String 25 | 26 | autoVerifiedAttributes: 27 | Type: CommaDelimitedList 28 | 29 | mfaConfiguration: 30 | Type: String 31 | 32 | mfaTypes: 33 | Type: CommaDelimitedList 34 | 35 | smsAuthenticationMessage: 36 | Type: String 37 | 38 | smsVerificationMessage: 39 | Type: String 40 | 41 | emailVerificationSubject: 42 | Type: String 43 | 44 | emailVerificationMessage: 45 | Type: String 46 | 47 | defaultPasswordPolicy: 48 | Type: String 49 | 50 | passwordPolicyMinLength: 51 | Type: Number 52 | 53 | passwordPolicyCharacters: 54 | Type: CommaDelimitedList 55 | 56 | requiredAttributes: 57 | Type: CommaDelimitedList 58 | 59 | userpoolClientGenerateSecret: 60 | Type: String 61 | 62 | userpoolClientRefreshTokenValidity: 63 | Type: Number 64 | 65 | userpoolClientWriteAttributes: 66 | Type: CommaDelimitedList 67 | 68 | userpoolClientReadAttributes: 69 | Type: CommaDelimitedList 70 | 71 | userpoolClientLambdaRole: 72 | Type: String 73 | 74 | userpoolClientSetAttributes: 75 | Type: String 76 | 77 | resourceName: 78 | Type: String 79 | 80 | authSelections: 81 | Type: String 82 | 83 | useDefault: 84 | Type: String 85 | 86 | dependsOn: 87 | Type: CommaDelimitedList 88 | 89 | Conditions: 90 | ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ] 91 | 92 | Resources: 93 | 94 | 95 | # BEGIN SNS ROLE RESOURCE 96 | SNSRole: 97 | # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process 98 | Type: AWS::IAM::Role 99 | Properties: 100 | RoleName: !If [ShouldNotCreateEnvResources, 'jobass8b1be0cb_sns-role', !Join ['',['jobass8b1be0cb_sns-role', '-', !Ref env]]] 101 | AssumeRolePolicyDocument: 102 | Version: "2012-10-17" 103 | Statement: 104 | - Sid: "" 105 | Effect: "Allow" 106 | Principal: 107 | Service: "cognito-idp.amazonaws.com" 108 | Action: 109 | - "sts:AssumeRole" 110 | Condition: 111 | StringEquals: 112 | sts:ExternalId: jobass8b1be0cb_role_external_id 113 | Policies: 114 | - 115 | PolicyName: jobass8b1be0cb-sns-policy 116 | PolicyDocument: 117 | Version: "2012-10-17" 118 | Statement: 119 | - 120 | Effect: "Allow" 121 | Action: 122 | - "sns:Publish" 123 | Resource: "*" 124 | # BEGIN USER POOL RESOURCES 125 | UserPool: 126 | # Created upon user selection 127 | # Depends on SNS Role for Arn if MFA is enabled 128 | Type: AWS::Cognito::UserPool 129 | UpdateReplacePolicy: Retain 130 | Properties: 131 | UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]] 132 | 133 | Schema: 134 | 135 | - 136 | Name: email 137 | Required: true 138 | Mutable: true 139 | 140 | 141 | 142 | 143 | AutoVerifiedAttributes: !Ref autoVerifiedAttributes 144 | 145 | 146 | EmailVerificationMessage: !Ref emailVerificationMessage 147 | EmailVerificationSubject: !Ref emailVerificationSubject 148 | 149 | Policies: 150 | PasswordPolicy: 151 | MinimumLength: !Ref passwordPolicyMinLength 152 | RequireLowercase: false 153 | RequireNumbers: false 154 | RequireSymbols: false 155 | RequireUppercase: false 156 | 157 | MfaConfiguration: !Ref mfaConfiguration 158 | SmsVerificationMessage: !Ref smsVerificationMessage 159 | SmsConfiguration: 160 | SnsCallerArn: !GetAtt SNSRole.Arn 161 | ExternalId: jobass8b1be0cb_role_external_id 162 | 163 | 164 | UserPoolClientWeb: 165 | # Created provide application access to user pool 166 | # Depends on UserPool for ID reference 167 | Type: "AWS::Cognito::UserPoolClient" 168 | Properties: 169 | ClientName: jobass8b1be0cb_app_clientWeb 170 | 171 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity 172 | UserPoolId: !Ref UserPool 173 | DependsOn: UserPool 174 | UserPoolClient: 175 | # Created provide application access to user pool 176 | # Depends on UserPool for ID reference 177 | Type: "AWS::Cognito::UserPoolClient" 178 | Properties: 179 | ClientName: jobass8b1be0cb_app_client 180 | 181 | GenerateSecret: !Ref userpoolClientGenerateSecret 182 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity 183 | UserPoolId: !Ref UserPool 184 | DependsOn: UserPool 185 | # BEGIN USER POOL LAMBDA RESOURCES 186 | UserPoolClientRole: 187 | # Created to execute Lambda which gets userpool app client config values 188 | Type: 'AWS::IAM::Role' 189 | Properties: 190 | RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',[!Ref userpoolClientLambdaRole, '-', !Ref env]]] 191 | AssumeRolePolicyDocument: 192 | Version: '2012-10-17' 193 | Statement: 194 | - Effect: Allow 195 | Principal: 196 | Service: 197 | - lambda.amazonaws.com 198 | Action: 199 | - 'sts:AssumeRole' 200 | DependsOn: UserPoolClient 201 | UserPoolClientLambda: 202 | # Lambda which gets userpool app client config values 203 | # Depends on UserPool for id 204 | # Depends on UserPoolClientRole for role ARN 205 | Type: 'AWS::Lambda::Function' 206 | Properties: 207 | Code: 208 | ZipFile: !Join 209 | - |+ 210 | - - 'const response = require(''cfn-response'');' 211 | - 'const aws = require(''aws-sdk'');' 212 | - 'const identity = new aws.CognitoIdentityServiceProvider();' 213 | - 'exports.handler = (event, context, callback) => {' 214 | - ' if (event.RequestType == ''Delete'') { ' 215 | - ' response.send(event, context, response.SUCCESS, {})' 216 | - ' }' 217 | - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {' 218 | - ' const params = {' 219 | - ' ClientId: event.ResourceProperties.clientId,' 220 | - ' UserPoolId: event.ResourceProperties.userpoolId' 221 | - ' };' 222 | - ' identity.describeUserPoolClient(params).promise()' 223 | - ' .then((res) => {' 224 | - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});' 225 | - ' })' 226 | - ' .catch((err) => {' 227 | - ' response.send(event, context, response.FAILED, {err});' 228 | - ' });' 229 | - ' }' 230 | - '};' 231 | Handler: index.handler 232 | Runtime: nodejs8.10 233 | Timeout: '300' 234 | Role: !GetAtt 235 | - UserPoolClientRole 236 | - Arn 237 | DependsOn: UserPoolClientRole 238 | UserPoolClientLambdaPolicy: 239 | # Sets userpool policy for the role that executes the Userpool Client Lambda 240 | # Depends on UserPool for Arn 241 | # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing 242 | Type: 'AWS::IAM::Policy' 243 | Properties: 244 | PolicyName: jobass8b1be0cb_userpoolclient_lambda_iam_policy 245 | Roles: 246 | - !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',[!Ref userpoolClientLambdaRole, '-', !Ref env]]] 247 | PolicyDocument: 248 | Version: '2012-10-17' 249 | Statement: 250 | - Effect: Allow 251 | Action: 252 | - 'cognito-idp:DescribeUserPoolClient' 253 | Resource: !GetAtt UserPool.Arn 254 | DependsOn: UserPoolClientLambda 255 | UserPoolClientLogPolicy: 256 | # Sets log policy for the role that executes the Userpool Client Lambda 257 | # Depends on UserPool for Arn 258 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing 259 | Type: 'AWS::IAM::Policy' 260 | Properties: 261 | PolicyName: jobass8b1be0cb_userpoolclient_lambda_log_policy 262 | Roles: 263 | - !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',[!Ref userpoolClientLambdaRole, '-', !Ref env]]] 264 | PolicyDocument: 265 | Version: 2012-10-17 266 | Statement: 267 | - Effect: Allow 268 | Action: 269 | - 'logs:CreateLogGroup' 270 | - 'logs:CreateLogStream' 271 | - 'logs:PutLogEvents' 272 | Resource: !Sub 273 | - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:* 274 | - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda} 275 | DependsOn: UserPoolClientLambdaPolicy 276 | UserPoolClientInputs: 277 | # Values passed to Userpool client Lambda 278 | # Depends on UserPool for Id 279 | # Depends on UserPoolClient for Id 280 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing 281 | Type: 'Custom::LambdaCallout' 282 | Properties: 283 | ServiceToken: !GetAtt UserPoolClientLambda.Arn 284 | clientId: !Ref UserPoolClient 285 | userpoolId: !Ref UserPool 286 | DependsOn: UserPoolClientLogPolicy 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | # BEGIN IDENTITY POOL RESOURCES 295 | 296 | 297 | IdentityPool: 298 | # Always created 299 | Type: AWS::Cognito::IdentityPool 300 | Properties: 301 | IdentityPoolName: !If [ShouldNotCreateEnvResources, 'jobassist8b1be0cb_identitypool_8b1be0cb', !Join ['',['jobassist8b1be0cb_identitypool_8b1be0cb', '__', !Ref env]]] 302 | 303 | CognitoIdentityProviders: 304 | - ClientId: !Ref UserPoolClient 305 | ProviderName: !Sub 306 | - cognito-idp.${region}.amazonaws.com/${client} 307 | - { region: !Ref "AWS::Region", client: !Ref UserPool} 308 | - ClientId: !Ref UserPoolClientWeb 309 | ProviderName: !Sub 310 | - cognito-idp.${region}.amazonaws.com/${client} 311 | - { region: !Ref "AWS::Region", client: !Ref UserPool} 312 | 313 | AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities 314 | 315 | 316 | DependsOn: UserPoolClientInputs 317 | 318 | 319 | IdentityPoolRoleMap: 320 | # Created to map Auth and Unauth roles to the identity pool 321 | # Depends on Identity Pool for ID ref 322 | Type: AWS::Cognito::IdentityPoolRoleAttachment 323 | Properties: 324 | IdentityPoolId: !Ref IdentityPool 325 | Roles: 326 | unauthenticated: !Ref unauthRoleArn 327 | authenticated: !Ref authRoleArn 328 | DependsOn: IdentityPool 329 | 330 | 331 | Outputs : 332 | 333 | IdentityPoolId: 334 | Value: !Ref 'IdentityPool' 335 | Description: Id for the identity pool 336 | IdentityPoolName: 337 | Value: !GetAtt IdentityPool.Name 338 | 339 | 340 | 341 | 342 | UserPoolId: 343 | Value: !Ref 'UserPool' 344 | Description: Id for the user pool 345 | UserPoolName: 346 | Value: !Ref userPoolName 347 | AppClientIDWeb: 348 | Value: !Ref 'UserPoolClientWeb' 349 | Description: The user pool app client id for web 350 | AppClientID: 351 | Value: !Ref 'UserPoolClient' 352 | Description: The user pool app client id 353 | AppClientSecret: 354 | Value: !GetAtt UserPoolClientInputs.appSecret 355 | 356 | 357 | 358 | 359 | 360 | 361 | -------------------------------------------------------------------------------- /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" : "getListing", 19 | "description" : null, 20 | "args" : [ { 21 | "name" : "id", 22 | "description" : null, 23 | "type" : { 24 | "kind" : "NON_NULL", 25 | "name" : null, 26 | "ofType" : { 27 | "kind" : "SCALAR", 28 | "name" : "ID", 29 | "ofType" : null 30 | } 31 | }, 32 | "defaultValue" : null 33 | } ], 34 | "type" : { 35 | "kind" : "OBJECT", 36 | "name" : "Listing", 37 | "ofType" : null 38 | }, 39 | "isDeprecated" : false, 40 | "deprecationReason" : null 41 | }, { 42 | "name" : "listListings", 43 | "description" : null, 44 | "args" : [ { 45 | "name" : "filter", 46 | "description" : null, 47 | "type" : { 48 | "kind" : "INPUT_OBJECT", 49 | "name" : "ModelListingFilterInput", 50 | "ofType" : null 51 | }, 52 | "defaultValue" : null 53 | }, { 54 | "name" : "limit", 55 | "description" : null, 56 | "type" : { 57 | "kind" : "SCALAR", 58 | "name" : "Int", 59 | "ofType" : null 60 | }, 61 | "defaultValue" : null 62 | }, { 63 | "name" : "nextToken", 64 | "description" : null, 65 | "type" : { 66 | "kind" : "SCALAR", 67 | "name" : "String", 68 | "ofType" : null 69 | }, 70 | "defaultValue" : null 71 | } ], 72 | "type" : { 73 | "kind" : "OBJECT", 74 | "name" : "ModelListingConnection", 75 | "ofType" : null 76 | }, 77 | "isDeprecated" : false, 78 | "deprecationReason" : null 79 | } ], 80 | "inputFields" : null, 81 | "interfaces" : [ ], 82 | "enumValues" : null, 83 | "possibleTypes" : null 84 | }, { 85 | "kind" : "OBJECT", 86 | "name" : "Listing", 87 | "description" : null, 88 | "fields" : [ { 89 | "name" : "id", 90 | "description" : null, 91 | "args" : [ ], 92 | "type" : { 93 | "kind" : "NON_NULL", 94 | "name" : null, 95 | "ofType" : { 96 | "kind" : "SCALAR", 97 | "name" : "ID", 98 | "ofType" : null 99 | } 100 | }, 101 | "isDeprecated" : false, 102 | "deprecationReason" : null 103 | }, { 104 | "name" : "title", 105 | "description" : null, 106 | "args" : [ ], 107 | "type" : { 108 | "kind" : "NON_NULL", 109 | "name" : null, 110 | "ofType" : { 111 | "kind" : "SCALAR", 112 | "name" : "String", 113 | "ofType" : null 114 | } 115 | }, 116 | "isDeprecated" : false, 117 | "deprecationReason" : null 118 | }, { 119 | "name" : "company", 120 | "description" : null, 121 | "args" : [ ], 122 | "type" : { 123 | "kind" : "NON_NULL", 124 | "name" : null, 125 | "ofType" : { 126 | "kind" : "SCALAR", 127 | "name" : "String", 128 | "ofType" : null 129 | } 130 | }, 131 | "isDeprecated" : false, 132 | "deprecationReason" : null 133 | }, { 134 | "name" : "url", 135 | "description" : null, 136 | "args" : [ ], 137 | "type" : { 138 | "kind" : "NON_NULL", 139 | "name" : null, 140 | "ofType" : { 141 | "kind" : "SCALAR", 142 | "name" : "String", 143 | "ofType" : null 144 | } 145 | }, 146 | "isDeprecated" : false, 147 | "deprecationReason" : null 148 | }, { 149 | "name" : "status", 150 | "description" : null, 151 | "args" : [ ], 152 | "type" : { 153 | "kind" : "NON_NULL", 154 | "name" : null, 155 | "ofType" : { 156 | "kind" : "ENUM", 157 | "name" : "Status", 158 | "ofType" : null 159 | } 160 | }, 161 | "isDeprecated" : false, 162 | "deprecationReason" : null 163 | }, { 164 | "name" : "favorite", 165 | "description" : null, 166 | "args" : [ ], 167 | "type" : { 168 | "kind" : "NON_NULL", 169 | "name" : null, 170 | "ofType" : { 171 | "kind" : "SCALAR", 172 | "name" : "Boolean", 173 | "ofType" : null 174 | } 175 | }, 176 | "isDeprecated" : false, 177 | "deprecationReason" : null 178 | }, { 179 | "name" : "note", 180 | "description" : null, 181 | "args" : [ ], 182 | "type" : { 183 | "kind" : "SCALAR", 184 | "name" : "String", 185 | "ofType" : null 186 | }, 187 | "isDeprecated" : false, 188 | "deprecationReason" : null 189 | }, { 190 | "name" : "relatedDate", 191 | "description" : null, 192 | "args" : [ ], 193 | "type" : { 194 | "kind" : "SCALAR", 195 | "name" : "String", 196 | "ofType" : null 197 | }, 198 | "isDeprecated" : false, 199 | "deprecationReason" : null 200 | }, { 201 | "name" : "contactName", 202 | "description" : null, 203 | "args" : [ ], 204 | "type" : { 205 | "kind" : "SCALAR", 206 | "name" : "String", 207 | "ofType" : null 208 | }, 209 | "isDeprecated" : false, 210 | "deprecationReason" : null 211 | }, { 212 | "name" : "contactEmail", 213 | "description" : null, 214 | "args" : [ ], 215 | "type" : { 216 | "kind" : "SCALAR", 217 | "name" : "String", 218 | "ofType" : null 219 | }, 220 | "isDeprecated" : false, 221 | "deprecationReason" : null 222 | }, { 223 | "name" : "contactPhoneNumber", 224 | "description" : null, 225 | "args" : [ ], 226 | "type" : { 227 | "kind" : "SCALAR", 228 | "name" : "String", 229 | "ofType" : null 230 | }, 231 | "isDeprecated" : false, 232 | "deprecationReason" : null 233 | } ], 234 | "inputFields" : null, 235 | "interfaces" : [ ], 236 | "enumValues" : null, 237 | "possibleTypes" : null 238 | }, { 239 | "kind" : "SCALAR", 240 | "name" : "ID", 241 | "description" : "Built-in ID", 242 | "fields" : null, 243 | "inputFields" : null, 244 | "interfaces" : null, 245 | "enumValues" : null, 246 | "possibleTypes" : null 247 | }, { 248 | "kind" : "SCALAR", 249 | "name" : "String", 250 | "description" : "Built-in String", 251 | "fields" : null, 252 | "inputFields" : null, 253 | "interfaces" : null, 254 | "enumValues" : null, 255 | "possibleTypes" : null 256 | }, { 257 | "kind" : "ENUM", 258 | "name" : "Status", 259 | "description" : null, 260 | "fields" : null, 261 | "inputFields" : null, 262 | "interfaces" : null, 263 | "enumValues" : [ { 264 | "name" : "APPLIED", 265 | "description" : null, 266 | "isDeprecated" : false, 267 | "deprecationReason" : null 268 | }, { 269 | "name" : "INTERESTED", 270 | "description" : null, 271 | "isDeprecated" : false, 272 | "deprecationReason" : null 273 | }, { 274 | "name" : "INTERVIEWING", 275 | "description" : null, 276 | "isDeprecated" : false, 277 | "deprecationReason" : null 278 | }, { 279 | "name" : "TAKE_HOME_ASSIGNMENT", 280 | "description" : null, 281 | "isDeprecated" : false, 282 | "deprecationReason" : null 283 | } ], 284 | "possibleTypes" : null 285 | }, { 286 | "kind" : "SCALAR", 287 | "name" : "Boolean", 288 | "description" : "Built-in Boolean", 289 | "fields" : null, 290 | "inputFields" : null, 291 | "interfaces" : null, 292 | "enumValues" : null, 293 | "possibleTypes" : null 294 | }, { 295 | "kind" : "OBJECT", 296 | "name" : "ModelListingConnection", 297 | "description" : null, 298 | "fields" : [ { 299 | "name" : "items", 300 | "description" : null, 301 | "args" : [ ], 302 | "type" : { 303 | "kind" : "LIST", 304 | "name" : null, 305 | "ofType" : { 306 | "kind" : "OBJECT", 307 | "name" : "Listing", 308 | "ofType" : null 309 | } 310 | }, 311 | "isDeprecated" : false, 312 | "deprecationReason" : null 313 | }, { 314 | "name" : "nextToken", 315 | "description" : null, 316 | "args" : [ ], 317 | "type" : { 318 | "kind" : "SCALAR", 319 | "name" : "String", 320 | "ofType" : null 321 | }, 322 | "isDeprecated" : false, 323 | "deprecationReason" : null 324 | } ], 325 | "inputFields" : null, 326 | "interfaces" : [ ], 327 | "enumValues" : null, 328 | "possibleTypes" : null 329 | }, { 330 | "kind" : "INPUT_OBJECT", 331 | "name" : "ModelListingFilterInput", 332 | "description" : null, 333 | "fields" : null, 334 | "inputFields" : [ { 335 | "name" : "id", 336 | "description" : null, 337 | "type" : { 338 | "kind" : "INPUT_OBJECT", 339 | "name" : "ModelIDFilterInput", 340 | "ofType" : null 341 | }, 342 | "defaultValue" : null 343 | }, { 344 | "name" : "title", 345 | "description" : null, 346 | "type" : { 347 | "kind" : "INPUT_OBJECT", 348 | "name" : "ModelStringFilterInput", 349 | "ofType" : null 350 | }, 351 | "defaultValue" : null 352 | }, { 353 | "name" : "company", 354 | "description" : null, 355 | "type" : { 356 | "kind" : "INPUT_OBJECT", 357 | "name" : "ModelStringFilterInput", 358 | "ofType" : null 359 | }, 360 | "defaultValue" : null 361 | }, { 362 | "name" : "url", 363 | "description" : null, 364 | "type" : { 365 | "kind" : "INPUT_OBJECT", 366 | "name" : "ModelStringFilterInput", 367 | "ofType" : null 368 | }, 369 | "defaultValue" : null 370 | }, { 371 | "name" : "status", 372 | "description" : null, 373 | "type" : { 374 | "kind" : "INPUT_OBJECT", 375 | "name" : "ModelStatusFilterInput", 376 | "ofType" : null 377 | }, 378 | "defaultValue" : null 379 | }, { 380 | "name" : "favorite", 381 | "description" : null, 382 | "type" : { 383 | "kind" : "INPUT_OBJECT", 384 | "name" : "ModelBooleanFilterInput", 385 | "ofType" : null 386 | }, 387 | "defaultValue" : null 388 | }, { 389 | "name" : "note", 390 | "description" : null, 391 | "type" : { 392 | "kind" : "INPUT_OBJECT", 393 | "name" : "ModelStringFilterInput", 394 | "ofType" : null 395 | }, 396 | "defaultValue" : null 397 | }, { 398 | "name" : "relatedDate", 399 | "description" : null, 400 | "type" : { 401 | "kind" : "INPUT_OBJECT", 402 | "name" : "ModelStringFilterInput", 403 | "ofType" : null 404 | }, 405 | "defaultValue" : null 406 | }, { 407 | "name" : "contactName", 408 | "description" : null, 409 | "type" : { 410 | "kind" : "INPUT_OBJECT", 411 | "name" : "ModelStringFilterInput", 412 | "ofType" : null 413 | }, 414 | "defaultValue" : null 415 | }, { 416 | "name" : "contactEmail", 417 | "description" : null, 418 | "type" : { 419 | "kind" : "INPUT_OBJECT", 420 | "name" : "ModelStringFilterInput", 421 | "ofType" : null 422 | }, 423 | "defaultValue" : null 424 | }, { 425 | "name" : "contactPhoneNumber", 426 | "description" : null, 427 | "type" : { 428 | "kind" : "INPUT_OBJECT", 429 | "name" : "ModelStringFilterInput", 430 | "ofType" : null 431 | }, 432 | "defaultValue" : null 433 | }, { 434 | "name" : "and", 435 | "description" : null, 436 | "type" : { 437 | "kind" : "LIST", 438 | "name" : null, 439 | "ofType" : { 440 | "kind" : "INPUT_OBJECT", 441 | "name" : "ModelListingFilterInput", 442 | "ofType" : null 443 | } 444 | }, 445 | "defaultValue" : null 446 | }, { 447 | "name" : "or", 448 | "description" : null, 449 | "type" : { 450 | "kind" : "LIST", 451 | "name" : null, 452 | "ofType" : { 453 | "kind" : "INPUT_OBJECT", 454 | "name" : "ModelListingFilterInput", 455 | "ofType" : null 456 | } 457 | }, 458 | "defaultValue" : null 459 | }, { 460 | "name" : "not", 461 | "description" : null, 462 | "type" : { 463 | "kind" : "INPUT_OBJECT", 464 | "name" : "ModelListingFilterInput", 465 | "ofType" : null 466 | }, 467 | "defaultValue" : null 468 | } ], 469 | "interfaces" : null, 470 | "enumValues" : null, 471 | "possibleTypes" : null 472 | }, { 473 | "kind" : "INPUT_OBJECT", 474 | "name" : "ModelIDFilterInput", 475 | "description" : null, 476 | "fields" : null, 477 | "inputFields" : [ { 478 | "name" : "ne", 479 | "description" : null, 480 | "type" : { 481 | "kind" : "SCALAR", 482 | "name" : "ID", 483 | "ofType" : null 484 | }, 485 | "defaultValue" : null 486 | }, { 487 | "name" : "eq", 488 | "description" : null, 489 | "type" : { 490 | "kind" : "SCALAR", 491 | "name" : "ID", 492 | "ofType" : null 493 | }, 494 | "defaultValue" : null 495 | }, { 496 | "name" : "le", 497 | "description" : null, 498 | "type" : { 499 | "kind" : "SCALAR", 500 | "name" : "ID", 501 | "ofType" : null 502 | }, 503 | "defaultValue" : null 504 | }, { 505 | "name" : "lt", 506 | "description" : null, 507 | "type" : { 508 | "kind" : "SCALAR", 509 | "name" : "ID", 510 | "ofType" : null 511 | }, 512 | "defaultValue" : null 513 | }, { 514 | "name" : "ge", 515 | "description" : null, 516 | "type" : { 517 | "kind" : "SCALAR", 518 | "name" : "ID", 519 | "ofType" : null 520 | }, 521 | "defaultValue" : null 522 | }, { 523 | "name" : "gt", 524 | "description" : null, 525 | "type" : { 526 | "kind" : "SCALAR", 527 | "name" : "ID", 528 | "ofType" : null 529 | }, 530 | "defaultValue" : null 531 | }, { 532 | "name" : "contains", 533 | "description" : null, 534 | "type" : { 535 | "kind" : "SCALAR", 536 | "name" : "ID", 537 | "ofType" : null 538 | }, 539 | "defaultValue" : null 540 | }, { 541 | "name" : "notContains", 542 | "description" : null, 543 | "type" : { 544 | "kind" : "SCALAR", 545 | "name" : "ID", 546 | "ofType" : null 547 | }, 548 | "defaultValue" : null 549 | }, { 550 | "name" : "between", 551 | "description" : null, 552 | "type" : { 553 | "kind" : "LIST", 554 | "name" : null, 555 | "ofType" : { 556 | "kind" : "SCALAR", 557 | "name" : "ID", 558 | "ofType" : null 559 | } 560 | }, 561 | "defaultValue" : null 562 | }, { 563 | "name" : "beginsWith", 564 | "description" : null, 565 | "type" : { 566 | "kind" : "SCALAR", 567 | "name" : "ID", 568 | "ofType" : null 569 | }, 570 | "defaultValue" : null 571 | } ], 572 | "interfaces" : null, 573 | "enumValues" : null, 574 | "possibleTypes" : null 575 | }, { 576 | "kind" : "INPUT_OBJECT", 577 | "name" : "ModelStringFilterInput", 578 | "description" : null, 579 | "fields" : null, 580 | "inputFields" : [ { 581 | "name" : "ne", 582 | "description" : null, 583 | "type" : { 584 | "kind" : "SCALAR", 585 | "name" : "String", 586 | "ofType" : null 587 | }, 588 | "defaultValue" : null 589 | }, { 590 | "name" : "eq", 591 | "description" : null, 592 | "type" : { 593 | "kind" : "SCALAR", 594 | "name" : "String", 595 | "ofType" : null 596 | }, 597 | "defaultValue" : null 598 | }, { 599 | "name" : "le", 600 | "description" : null, 601 | "type" : { 602 | "kind" : "SCALAR", 603 | "name" : "String", 604 | "ofType" : null 605 | }, 606 | "defaultValue" : null 607 | }, { 608 | "name" : "lt", 609 | "description" : null, 610 | "type" : { 611 | "kind" : "SCALAR", 612 | "name" : "String", 613 | "ofType" : null 614 | }, 615 | "defaultValue" : null 616 | }, { 617 | "name" : "ge", 618 | "description" : null, 619 | "type" : { 620 | "kind" : "SCALAR", 621 | "name" : "String", 622 | "ofType" : null 623 | }, 624 | "defaultValue" : null 625 | }, { 626 | "name" : "gt", 627 | "description" : null, 628 | "type" : { 629 | "kind" : "SCALAR", 630 | "name" : "String", 631 | "ofType" : null 632 | }, 633 | "defaultValue" : null 634 | }, { 635 | "name" : "contains", 636 | "description" : null, 637 | "type" : { 638 | "kind" : "SCALAR", 639 | "name" : "String", 640 | "ofType" : null 641 | }, 642 | "defaultValue" : null 643 | }, { 644 | "name" : "notContains", 645 | "description" : null, 646 | "type" : { 647 | "kind" : "SCALAR", 648 | "name" : "String", 649 | "ofType" : null 650 | }, 651 | "defaultValue" : null 652 | }, { 653 | "name" : "between", 654 | "description" : null, 655 | "type" : { 656 | "kind" : "LIST", 657 | "name" : null, 658 | "ofType" : { 659 | "kind" : "SCALAR", 660 | "name" : "String", 661 | "ofType" : null 662 | } 663 | }, 664 | "defaultValue" : null 665 | }, { 666 | "name" : "beginsWith", 667 | "description" : null, 668 | "type" : { 669 | "kind" : "SCALAR", 670 | "name" : "String", 671 | "ofType" : null 672 | }, 673 | "defaultValue" : null 674 | } ], 675 | "interfaces" : null, 676 | "enumValues" : null, 677 | "possibleTypes" : null 678 | }, { 679 | "kind" : "INPUT_OBJECT", 680 | "name" : "ModelStatusFilterInput", 681 | "description" : null, 682 | "fields" : null, 683 | "inputFields" : [ { 684 | "name" : "eq", 685 | "description" : null, 686 | "type" : { 687 | "kind" : "ENUM", 688 | "name" : "Status", 689 | "ofType" : null 690 | }, 691 | "defaultValue" : null 692 | }, { 693 | "name" : "ne", 694 | "description" : null, 695 | "type" : { 696 | "kind" : "ENUM", 697 | "name" : "Status", 698 | "ofType" : null 699 | }, 700 | "defaultValue" : null 701 | } ], 702 | "interfaces" : null, 703 | "enumValues" : null, 704 | "possibleTypes" : null 705 | }, { 706 | "kind" : "INPUT_OBJECT", 707 | "name" : "ModelBooleanFilterInput", 708 | "description" : null, 709 | "fields" : null, 710 | "inputFields" : [ { 711 | "name" : "ne", 712 | "description" : null, 713 | "type" : { 714 | "kind" : "SCALAR", 715 | "name" : "Boolean", 716 | "ofType" : null 717 | }, 718 | "defaultValue" : null 719 | }, { 720 | "name" : "eq", 721 | "description" : null, 722 | "type" : { 723 | "kind" : "SCALAR", 724 | "name" : "Boolean", 725 | "ofType" : null 726 | }, 727 | "defaultValue" : null 728 | } ], 729 | "interfaces" : null, 730 | "enumValues" : null, 731 | "possibleTypes" : null 732 | }, { 733 | "kind" : "SCALAR", 734 | "name" : "Int", 735 | "description" : "Built-in Int", 736 | "fields" : null, 737 | "inputFields" : null, 738 | "interfaces" : null, 739 | "enumValues" : null, 740 | "possibleTypes" : null 741 | }, { 742 | "kind" : "OBJECT", 743 | "name" : "Mutation", 744 | "description" : null, 745 | "fields" : [ { 746 | "name" : "createListing", 747 | "description" : null, 748 | "args" : [ { 749 | "name" : "input", 750 | "description" : null, 751 | "type" : { 752 | "kind" : "NON_NULL", 753 | "name" : null, 754 | "ofType" : { 755 | "kind" : "INPUT_OBJECT", 756 | "name" : "CreateListingInput", 757 | "ofType" : null 758 | } 759 | }, 760 | "defaultValue" : null 761 | } ], 762 | "type" : { 763 | "kind" : "OBJECT", 764 | "name" : "Listing", 765 | "ofType" : null 766 | }, 767 | "isDeprecated" : false, 768 | "deprecationReason" : null 769 | }, { 770 | "name" : "updateListing", 771 | "description" : null, 772 | "args" : [ { 773 | "name" : "input", 774 | "description" : null, 775 | "type" : { 776 | "kind" : "NON_NULL", 777 | "name" : null, 778 | "ofType" : { 779 | "kind" : "INPUT_OBJECT", 780 | "name" : "UpdateListingInput", 781 | "ofType" : null 782 | } 783 | }, 784 | "defaultValue" : null 785 | } ], 786 | "type" : { 787 | "kind" : "OBJECT", 788 | "name" : "Listing", 789 | "ofType" : null 790 | }, 791 | "isDeprecated" : false, 792 | "deprecationReason" : null 793 | }, { 794 | "name" : "deleteListing", 795 | "description" : null, 796 | "args" : [ { 797 | "name" : "input", 798 | "description" : null, 799 | "type" : { 800 | "kind" : "NON_NULL", 801 | "name" : null, 802 | "ofType" : { 803 | "kind" : "INPUT_OBJECT", 804 | "name" : "DeleteListingInput", 805 | "ofType" : null 806 | } 807 | }, 808 | "defaultValue" : null 809 | } ], 810 | "type" : { 811 | "kind" : "OBJECT", 812 | "name" : "Listing", 813 | "ofType" : null 814 | }, 815 | "isDeprecated" : false, 816 | "deprecationReason" : null 817 | } ], 818 | "inputFields" : null, 819 | "interfaces" : [ ], 820 | "enumValues" : null, 821 | "possibleTypes" : null 822 | }, { 823 | "kind" : "INPUT_OBJECT", 824 | "name" : "CreateListingInput", 825 | "description" : null, 826 | "fields" : null, 827 | "inputFields" : [ { 828 | "name" : "id", 829 | "description" : null, 830 | "type" : { 831 | "kind" : "SCALAR", 832 | "name" : "ID", 833 | "ofType" : null 834 | }, 835 | "defaultValue" : null 836 | }, { 837 | "name" : "title", 838 | "description" : null, 839 | "type" : { 840 | "kind" : "NON_NULL", 841 | "name" : null, 842 | "ofType" : { 843 | "kind" : "SCALAR", 844 | "name" : "String", 845 | "ofType" : null 846 | } 847 | }, 848 | "defaultValue" : null 849 | }, { 850 | "name" : "company", 851 | "description" : null, 852 | "type" : { 853 | "kind" : "NON_NULL", 854 | "name" : null, 855 | "ofType" : { 856 | "kind" : "SCALAR", 857 | "name" : "String", 858 | "ofType" : null 859 | } 860 | }, 861 | "defaultValue" : null 862 | }, { 863 | "name" : "url", 864 | "description" : null, 865 | "type" : { 866 | "kind" : "NON_NULL", 867 | "name" : null, 868 | "ofType" : { 869 | "kind" : "SCALAR", 870 | "name" : "String", 871 | "ofType" : null 872 | } 873 | }, 874 | "defaultValue" : null 875 | }, { 876 | "name" : "status", 877 | "description" : null, 878 | "type" : { 879 | "kind" : "NON_NULL", 880 | "name" : null, 881 | "ofType" : { 882 | "kind" : "ENUM", 883 | "name" : "Status", 884 | "ofType" : null 885 | } 886 | }, 887 | "defaultValue" : null 888 | }, { 889 | "name" : "favorite", 890 | "description" : null, 891 | "type" : { 892 | "kind" : "NON_NULL", 893 | "name" : null, 894 | "ofType" : { 895 | "kind" : "SCALAR", 896 | "name" : "Boolean", 897 | "ofType" : null 898 | } 899 | }, 900 | "defaultValue" : null 901 | }, { 902 | "name" : "note", 903 | "description" : null, 904 | "type" : { 905 | "kind" : "SCALAR", 906 | "name" : "String", 907 | "ofType" : null 908 | }, 909 | "defaultValue" : null 910 | }, { 911 | "name" : "relatedDate", 912 | "description" : null, 913 | "type" : { 914 | "kind" : "SCALAR", 915 | "name" : "String", 916 | "ofType" : null 917 | }, 918 | "defaultValue" : null 919 | }, { 920 | "name" : "contactName", 921 | "description" : null, 922 | "type" : { 923 | "kind" : "SCALAR", 924 | "name" : "String", 925 | "ofType" : null 926 | }, 927 | "defaultValue" : null 928 | }, { 929 | "name" : "contactEmail", 930 | "description" : null, 931 | "type" : { 932 | "kind" : "SCALAR", 933 | "name" : "String", 934 | "ofType" : null 935 | }, 936 | "defaultValue" : null 937 | }, { 938 | "name" : "contactPhoneNumber", 939 | "description" : null, 940 | "type" : { 941 | "kind" : "SCALAR", 942 | "name" : "String", 943 | "ofType" : null 944 | }, 945 | "defaultValue" : null 946 | } ], 947 | "interfaces" : null, 948 | "enumValues" : null, 949 | "possibleTypes" : null 950 | }, { 951 | "kind" : "INPUT_OBJECT", 952 | "name" : "UpdateListingInput", 953 | "description" : null, 954 | "fields" : null, 955 | "inputFields" : [ { 956 | "name" : "id", 957 | "description" : null, 958 | "type" : { 959 | "kind" : "NON_NULL", 960 | "name" : null, 961 | "ofType" : { 962 | "kind" : "SCALAR", 963 | "name" : "ID", 964 | "ofType" : null 965 | } 966 | }, 967 | "defaultValue" : null 968 | }, { 969 | "name" : "title", 970 | "description" : null, 971 | "type" : { 972 | "kind" : "SCALAR", 973 | "name" : "String", 974 | "ofType" : null 975 | }, 976 | "defaultValue" : null 977 | }, { 978 | "name" : "company", 979 | "description" : null, 980 | "type" : { 981 | "kind" : "SCALAR", 982 | "name" : "String", 983 | "ofType" : null 984 | }, 985 | "defaultValue" : null 986 | }, { 987 | "name" : "url", 988 | "description" : null, 989 | "type" : { 990 | "kind" : "SCALAR", 991 | "name" : "String", 992 | "ofType" : null 993 | }, 994 | "defaultValue" : null 995 | }, { 996 | "name" : "status", 997 | "description" : null, 998 | "type" : { 999 | "kind" : "ENUM", 1000 | "name" : "Status", 1001 | "ofType" : null 1002 | }, 1003 | "defaultValue" : null 1004 | }, { 1005 | "name" : "favorite", 1006 | "description" : null, 1007 | "type" : { 1008 | "kind" : "SCALAR", 1009 | "name" : "Boolean", 1010 | "ofType" : null 1011 | }, 1012 | "defaultValue" : null 1013 | }, { 1014 | "name" : "note", 1015 | "description" : null, 1016 | "type" : { 1017 | "kind" : "SCALAR", 1018 | "name" : "String", 1019 | "ofType" : null 1020 | }, 1021 | "defaultValue" : null 1022 | }, { 1023 | "name" : "relatedDate", 1024 | "description" : null, 1025 | "type" : { 1026 | "kind" : "SCALAR", 1027 | "name" : "String", 1028 | "ofType" : null 1029 | }, 1030 | "defaultValue" : null 1031 | }, { 1032 | "name" : "contactName", 1033 | "description" : null, 1034 | "type" : { 1035 | "kind" : "SCALAR", 1036 | "name" : "String", 1037 | "ofType" : null 1038 | }, 1039 | "defaultValue" : null 1040 | }, { 1041 | "name" : "contactEmail", 1042 | "description" : null, 1043 | "type" : { 1044 | "kind" : "SCALAR", 1045 | "name" : "String", 1046 | "ofType" : null 1047 | }, 1048 | "defaultValue" : null 1049 | }, { 1050 | "name" : "contactPhoneNumber", 1051 | "description" : null, 1052 | "type" : { 1053 | "kind" : "SCALAR", 1054 | "name" : "String", 1055 | "ofType" : null 1056 | }, 1057 | "defaultValue" : null 1058 | } ], 1059 | "interfaces" : null, 1060 | "enumValues" : null, 1061 | "possibleTypes" : null 1062 | }, { 1063 | "kind" : "INPUT_OBJECT", 1064 | "name" : "DeleteListingInput", 1065 | "description" : null, 1066 | "fields" : null, 1067 | "inputFields" : [ { 1068 | "name" : "id", 1069 | "description" : null, 1070 | "type" : { 1071 | "kind" : "SCALAR", 1072 | "name" : "ID", 1073 | "ofType" : null 1074 | }, 1075 | "defaultValue" : null 1076 | } ], 1077 | "interfaces" : null, 1078 | "enumValues" : null, 1079 | "possibleTypes" : null 1080 | }, { 1081 | "kind" : "OBJECT", 1082 | "name" : "Subscription", 1083 | "description" : null, 1084 | "fields" : [ { 1085 | "name" : "onListingAdded", 1086 | "description" : null, 1087 | "args" : [ ], 1088 | "type" : { 1089 | "kind" : "OBJECT", 1090 | "name" : "Listing", 1091 | "ofType" : null 1092 | }, 1093 | "isDeprecated" : false, 1094 | "deprecationReason" : null 1095 | }, { 1096 | "name" : "onListingUpdated", 1097 | "description" : null, 1098 | "args" : [ ], 1099 | "type" : { 1100 | "kind" : "OBJECT", 1101 | "name" : "Listing", 1102 | "ofType" : null 1103 | }, 1104 | "isDeprecated" : false, 1105 | "deprecationReason" : null 1106 | }, { 1107 | "name" : "onListingRemoved", 1108 | "description" : null, 1109 | "args" : [ ], 1110 | "type" : { 1111 | "kind" : "OBJECT", 1112 | "name" : "Listing", 1113 | "ofType" : null 1114 | }, 1115 | "isDeprecated" : false, 1116 | "deprecationReason" : null 1117 | }, { 1118 | "name" : "onCreateListing", 1119 | "description" : null, 1120 | "args" : [ ], 1121 | "type" : { 1122 | "kind" : "OBJECT", 1123 | "name" : "Listing", 1124 | "ofType" : null 1125 | }, 1126 | "isDeprecated" : false, 1127 | "deprecationReason" : null 1128 | }, { 1129 | "name" : "onUpdateListing", 1130 | "description" : null, 1131 | "args" : [ ], 1132 | "type" : { 1133 | "kind" : "OBJECT", 1134 | "name" : "Listing", 1135 | "ofType" : null 1136 | }, 1137 | "isDeprecated" : false, 1138 | "deprecationReason" : null 1139 | }, { 1140 | "name" : "onDeleteListing", 1141 | "description" : null, 1142 | "args" : [ ], 1143 | "type" : { 1144 | "kind" : "OBJECT", 1145 | "name" : "Listing", 1146 | "ofType" : null 1147 | }, 1148 | "isDeprecated" : false, 1149 | "deprecationReason" : null 1150 | } ], 1151 | "inputFields" : null, 1152 | "interfaces" : [ ], 1153 | "enumValues" : null, 1154 | "possibleTypes" : null 1155 | }, { 1156 | "kind" : "INPUT_OBJECT", 1157 | "name" : "ModelFloatFilterInput", 1158 | "description" : null, 1159 | "fields" : null, 1160 | "inputFields" : [ { 1161 | "name" : "ne", 1162 | "description" : null, 1163 | "type" : { 1164 | "kind" : "SCALAR", 1165 | "name" : "Float", 1166 | "ofType" : null 1167 | }, 1168 | "defaultValue" : null 1169 | }, { 1170 | "name" : "eq", 1171 | "description" : null, 1172 | "type" : { 1173 | "kind" : "SCALAR", 1174 | "name" : "Float", 1175 | "ofType" : null 1176 | }, 1177 | "defaultValue" : null 1178 | }, { 1179 | "name" : "le", 1180 | "description" : null, 1181 | "type" : { 1182 | "kind" : "SCALAR", 1183 | "name" : "Float", 1184 | "ofType" : null 1185 | }, 1186 | "defaultValue" : null 1187 | }, { 1188 | "name" : "lt", 1189 | "description" : null, 1190 | "type" : { 1191 | "kind" : "SCALAR", 1192 | "name" : "Float", 1193 | "ofType" : null 1194 | }, 1195 | "defaultValue" : null 1196 | }, { 1197 | "name" : "ge", 1198 | "description" : null, 1199 | "type" : { 1200 | "kind" : "SCALAR", 1201 | "name" : "Float", 1202 | "ofType" : null 1203 | }, 1204 | "defaultValue" : null 1205 | }, { 1206 | "name" : "gt", 1207 | "description" : null, 1208 | "type" : { 1209 | "kind" : "SCALAR", 1210 | "name" : "Float", 1211 | "ofType" : null 1212 | }, 1213 | "defaultValue" : null 1214 | }, { 1215 | "name" : "contains", 1216 | "description" : null, 1217 | "type" : { 1218 | "kind" : "SCALAR", 1219 | "name" : "Float", 1220 | "ofType" : null 1221 | }, 1222 | "defaultValue" : null 1223 | }, { 1224 | "name" : "notContains", 1225 | "description" : null, 1226 | "type" : { 1227 | "kind" : "SCALAR", 1228 | "name" : "Float", 1229 | "ofType" : null 1230 | }, 1231 | "defaultValue" : null 1232 | }, { 1233 | "name" : "between", 1234 | "description" : null, 1235 | "type" : { 1236 | "kind" : "LIST", 1237 | "name" : null, 1238 | "ofType" : { 1239 | "kind" : "SCALAR", 1240 | "name" : "Float", 1241 | "ofType" : null 1242 | } 1243 | }, 1244 | "defaultValue" : null 1245 | } ], 1246 | "interfaces" : null, 1247 | "enumValues" : null, 1248 | "possibleTypes" : null 1249 | }, { 1250 | "kind" : "SCALAR", 1251 | "name" : "Float", 1252 | "description" : "Built-in Float", 1253 | "fields" : null, 1254 | "inputFields" : null, 1255 | "interfaces" : null, 1256 | "enumValues" : null, 1257 | "possibleTypes" : null 1258 | }, { 1259 | "kind" : "ENUM", 1260 | "name" : "ModelSortDirection", 1261 | "description" : null, 1262 | "fields" : null, 1263 | "inputFields" : null, 1264 | "interfaces" : null, 1265 | "enumValues" : [ { 1266 | "name" : "ASC", 1267 | "description" : null, 1268 | "isDeprecated" : false, 1269 | "deprecationReason" : null 1270 | }, { 1271 | "name" : "DESC", 1272 | "description" : null, 1273 | "isDeprecated" : false, 1274 | "deprecationReason" : null 1275 | } ], 1276 | "possibleTypes" : null 1277 | }, { 1278 | "kind" : "INPUT_OBJECT", 1279 | "name" : "ModelIntFilterInput", 1280 | "description" : null, 1281 | "fields" : null, 1282 | "inputFields" : [ { 1283 | "name" : "ne", 1284 | "description" : null, 1285 | "type" : { 1286 | "kind" : "SCALAR", 1287 | "name" : "Int", 1288 | "ofType" : null 1289 | }, 1290 | "defaultValue" : null 1291 | }, { 1292 | "name" : "eq", 1293 | "description" : null, 1294 | "type" : { 1295 | "kind" : "SCALAR", 1296 | "name" : "Int", 1297 | "ofType" : null 1298 | }, 1299 | "defaultValue" : null 1300 | }, { 1301 | "name" : "le", 1302 | "description" : null, 1303 | "type" : { 1304 | "kind" : "SCALAR", 1305 | "name" : "Int", 1306 | "ofType" : null 1307 | }, 1308 | "defaultValue" : null 1309 | }, { 1310 | "name" : "lt", 1311 | "description" : null, 1312 | "type" : { 1313 | "kind" : "SCALAR", 1314 | "name" : "Int", 1315 | "ofType" : null 1316 | }, 1317 | "defaultValue" : null 1318 | }, { 1319 | "name" : "ge", 1320 | "description" : null, 1321 | "type" : { 1322 | "kind" : "SCALAR", 1323 | "name" : "Int", 1324 | "ofType" : null 1325 | }, 1326 | "defaultValue" : null 1327 | }, { 1328 | "name" : "gt", 1329 | "description" : null, 1330 | "type" : { 1331 | "kind" : "SCALAR", 1332 | "name" : "Int", 1333 | "ofType" : null 1334 | }, 1335 | "defaultValue" : null 1336 | }, { 1337 | "name" : "contains", 1338 | "description" : null, 1339 | "type" : { 1340 | "kind" : "SCALAR", 1341 | "name" : "Int", 1342 | "ofType" : null 1343 | }, 1344 | "defaultValue" : null 1345 | }, { 1346 | "name" : "notContains", 1347 | "description" : null, 1348 | "type" : { 1349 | "kind" : "SCALAR", 1350 | "name" : "Int", 1351 | "ofType" : null 1352 | }, 1353 | "defaultValue" : null 1354 | }, { 1355 | "name" : "between", 1356 | "description" : null, 1357 | "type" : { 1358 | "kind" : "LIST", 1359 | "name" : null, 1360 | "ofType" : { 1361 | "kind" : "SCALAR", 1362 | "name" : "Int", 1363 | "ofType" : null 1364 | } 1365 | }, 1366 | "defaultValue" : null 1367 | } ], 1368 | "interfaces" : null, 1369 | "enumValues" : null, 1370 | "possibleTypes" : null 1371 | }, { 1372 | "kind" : "OBJECT", 1373 | "name" : "__Schema", 1374 | "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.", 1375 | "fields" : [ { 1376 | "name" : "types", 1377 | "description" : "A list of all types supported by this server.", 1378 | "args" : [ ], 1379 | "type" : { 1380 | "kind" : "NON_NULL", 1381 | "name" : null, 1382 | "ofType" : { 1383 | "kind" : "LIST", 1384 | "name" : null, 1385 | "ofType" : { 1386 | "kind" : "NON_NULL", 1387 | "name" : null, 1388 | "ofType" : { 1389 | "kind" : "OBJECT", 1390 | "name" : "__Type", 1391 | "ofType" : null 1392 | } 1393 | } 1394 | } 1395 | }, 1396 | "isDeprecated" : false, 1397 | "deprecationReason" : null 1398 | }, { 1399 | "name" : "queryType", 1400 | "description" : "The type that query operations will be rooted at.", 1401 | "args" : [ ], 1402 | "type" : { 1403 | "kind" : "NON_NULL", 1404 | "name" : null, 1405 | "ofType" : { 1406 | "kind" : "OBJECT", 1407 | "name" : "__Type", 1408 | "ofType" : null 1409 | } 1410 | }, 1411 | "isDeprecated" : false, 1412 | "deprecationReason" : null 1413 | }, { 1414 | "name" : "mutationType", 1415 | "description" : "If this server supports mutation, the type that mutation operations will be rooted at.", 1416 | "args" : [ ], 1417 | "type" : { 1418 | "kind" : "OBJECT", 1419 | "name" : "__Type", 1420 | "ofType" : null 1421 | }, 1422 | "isDeprecated" : false, 1423 | "deprecationReason" : null 1424 | }, { 1425 | "name" : "directives", 1426 | "description" : "'A list of all directives supported by this server.", 1427 | "args" : [ ], 1428 | "type" : { 1429 | "kind" : "NON_NULL", 1430 | "name" : null, 1431 | "ofType" : { 1432 | "kind" : "LIST", 1433 | "name" : null, 1434 | "ofType" : { 1435 | "kind" : "NON_NULL", 1436 | "name" : null, 1437 | "ofType" : { 1438 | "kind" : "OBJECT", 1439 | "name" : "__Directive", 1440 | "ofType" : null 1441 | } 1442 | } 1443 | } 1444 | }, 1445 | "isDeprecated" : false, 1446 | "deprecationReason" : null 1447 | }, { 1448 | "name" : "subscriptionType", 1449 | "description" : "'If this server support subscription, the type that subscription operations will be rooted at.", 1450 | "args" : [ ], 1451 | "type" : { 1452 | "kind" : "OBJECT", 1453 | "name" : "__Type", 1454 | "ofType" : null 1455 | }, 1456 | "isDeprecated" : false, 1457 | "deprecationReason" : null 1458 | } ], 1459 | "inputFields" : null, 1460 | "interfaces" : [ ], 1461 | "enumValues" : null, 1462 | "possibleTypes" : null 1463 | }, { 1464 | "kind" : "OBJECT", 1465 | "name" : "__Type", 1466 | "description" : null, 1467 | "fields" : [ { 1468 | "name" : "kind", 1469 | "description" : null, 1470 | "args" : [ ], 1471 | "type" : { 1472 | "kind" : "NON_NULL", 1473 | "name" : null, 1474 | "ofType" : { 1475 | "kind" : "ENUM", 1476 | "name" : "__TypeKind", 1477 | "ofType" : null 1478 | } 1479 | }, 1480 | "isDeprecated" : false, 1481 | "deprecationReason" : null 1482 | }, { 1483 | "name" : "name", 1484 | "description" : null, 1485 | "args" : [ ], 1486 | "type" : { 1487 | "kind" : "SCALAR", 1488 | "name" : "String", 1489 | "ofType" : null 1490 | }, 1491 | "isDeprecated" : false, 1492 | "deprecationReason" : null 1493 | }, { 1494 | "name" : "description", 1495 | "description" : null, 1496 | "args" : [ ], 1497 | "type" : { 1498 | "kind" : "SCALAR", 1499 | "name" : "String", 1500 | "ofType" : null 1501 | }, 1502 | "isDeprecated" : false, 1503 | "deprecationReason" : null 1504 | }, { 1505 | "name" : "fields", 1506 | "description" : null, 1507 | "args" : [ { 1508 | "name" : "includeDeprecated", 1509 | "description" : null, 1510 | "type" : { 1511 | "kind" : "SCALAR", 1512 | "name" : "Boolean", 1513 | "ofType" : null 1514 | }, 1515 | "defaultValue" : "false" 1516 | } ], 1517 | "type" : { 1518 | "kind" : "LIST", 1519 | "name" : null, 1520 | "ofType" : { 1521 | "kind" : "NON_NULL", 1522 | "name" : null, 1523 | "ofType" : { 1524 | "kind" : "OBJECT", 1525 | "name" : "__Field", 1526 | "ofType" : null 1527 | } 1528 | } 1529 | }, 1530 | "isDeprecated" : false, 1531 | "deprecationReason" : null 1532 | }, { 1533 | "name" : "interfaces", 1534 | "description" : null, 1535 | "args" : [ ], 1536 | "type" : { 1537 | "kind" : "LIST", 1538 | "name" : null, 1539 | "ofType" : { 1540 | "kind" : "NON_NULL", 1541 | "name" : null, 1542 | "ofType" : { 1543 | "kind" : "OBJECT", 1544 | "name" : "__Type", 1545 | "ofType" : null 1546 | } 1547 | } 1548 | }, 1549 | "isDeprecated" : false, 1550 | "deprecationReason" : null 1551 | }, { 1552 | "name" : "possibleTypes", 1553 | "description" : null, 1554 | "args" : [ ], 1555 | "type" : { 1556 | "kind" : "LIST", 1557 | "name" : null, 1558 | "ofType" : { 1559 | "kind" : "NON_NULL", 1560 | "name" : null, 1561 | "ofType" : { 1562 | "kind" : "OBJECT", 1563 | "name" : "__Type", 1564 | "ofType" : null 1565 | } 1566 | } 1567 | }, 1568 | "isDeprecated" : false, 1569 | "deprecationReason" : null 1570 | }, { 1571 | "name" : "enumValues", 1572 | "description" : null, 1573 | "args" : [ { 1574 | "name" : "includeDeprecated", 1575 | "description" : null, 1576 | "type" : { 1577 | "kind" : "SCALAR", 1578 | "name" : "Boolean", 1579 | "ofType" : null 1580 | }, 1581 | "defaultValue" : "false" 1582 | } ], 1583 | "type" : { 1584 | "kind" : "LIST", 1585 | "name" : null, 1586 | "ofType" : { 1587 | "kind" : "NON_NULL", 1588 | "name" : null, 1589 | "ofType" : { 1590 | "kind" : "OBJECT", 1591 | "name" : "__EnumValue", 1592 | "ofType" : null 1593 | } 1594 | } 1595 | }, 1596 | "isDeprecated" : false, 1597 | "deprecationReason" : null 1598 | }, { 1599 | "name" : "inputFields", 1600 | "description" : null, 1601 | "args" : [ ], 1602 | "type" : { 1603 | "kind" : "LIST", 1604 | "name" : null, 1605 | "ofType" : { 1606 | "kind" : "NON_NULL", 1607 | "name" : null, 1608 | "ofType" : { 1609 | "kind" : "OBJECT", 1610 | "name" : "__InputValue", 1611 | "ofType" : null 1612 | } 1613 | } 1614 | }, 1615 | "isDeprecated" : false, 1616 | "deprecationReason" : null 1617 | }, { 1618 | "name" : "ofType", 1619 | "description" : null, 1620 | "args" : [ ], 1621 | "type" : { 1622 | "kind" : "OBJECT", 1623 | "name" : "__Type", 1624 | "ofType" : null 1625 | }, 1626 | "isDeprecated" : false, 1627 | "deprecationReason" : null 1628 | } ], 1629 | "inputFields" : null, 1630 | "interfaces" : [ ], 1631 | "enumValues" : null, 1632 | "possibleTypes" : null 1633 | }, { 1634 | "kind" : "ENUM", 1635 | "name" : "__TypeKind", 1636 | "description" : "An enum describing what kind of type a given __Type is", 1637 | "fields" : null, 1638 | "inputFields" : null, 1639 | "interfaces" : null, 1640 | "enumValues" : [ { 1641 | "name" : "SCALAR", 1642 | "description" : "Indicates this type is a scalar.", 1643 | "isDeprecated" : false, 1644 | "deprecationReason" : null 1645 | }, { 1646 | "name" : "OBJECT", 1647 | "description" : "Indicates this type is an object. `fields` and `interfaces` are valid fields.", 1648 | "isDeprecated" : false, 1649 | "deprecationReason" : null 1650 | }, { 1651 | "name" : "INTERFACE", 1652 | "description" : "Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.", 1653 | "isDeprecated" : false, 1654 | "deprecationReason" : null 1655 | }, { 1656 | "name" : "UNION", 1657 | "description" : "Indicates this type is a union. `possibleTypes` is a valid field.", 1658 | "isDeprecated" : false, 1659 | "deprecationReason" : null 1660 | }, { 1661 | "name" : "ENUM", 1662 | "description" : "Indicates this type is an enum. `enumValues` is a valid field.", 1663 | "isDeprecated" : false, 1664 | "deprecationReason" : null 1665 | }, { 1666 | "name" : "INPUT_OBJECT", 1667 | "description" : "Indicates this type is an input object. `inputFields` is a valid field.", 1668 | "isDeprecated" : false, 1669 | "deprecationReason" : null 1670 | }, { 1671 | "name" : "LIST", 1672 | "description" : "Indicates this type is a list. `ofType` is a valid field.", 1673 | "isDeprecated" : false, 1674 | "deprecationReason" : null 1675 | }, { 1676 | "name" : "NON_NULL", 1677 | "description" : "Indicates this type is a non-null. `ofType` is a valid field.", 1678 | "isDeprecated" : false, 1679 | "deprecationReason" : null 1680 | } ], 1681 | "possibleTypes" : null 1682 | }, { 1683 | "kind" : "OBJECT", 1684 | "name" : "__Field", 1685 | "description" : null, 1686 | "fields" : [ { 1687 | "name" : "name", 1688 | "description" : null, 1689 | "args" : [ ], 1690 | "type" : { 1691 | "kind" : "NON_NULL", 1692 | "name" : null, 1693 | "ofType" : { 1694 | "kind" : "SCALAR", 1695 | "name" : "String", 1696 | "ofType" : null 1697 | } 1698 | }, 1699 | "isDeprecated" : false, 1700 | "deprecationReason" : null 1701 | }, { 1702 | "name" : "description", 1703 | "description" : null, 1704 | "args" : [ ], 1705 | "type" : { 1706 | "kind" : "SCALAR", 1707 | "name" : "String", 1708 | "ofType" : null 1709 | }, 1710 | "isDeprecated" : false, 1711 | "deprecationReason" : null 1712 | }, { 1713 | "name" : "args", 1714 | "description" : null, 1715 | "args" : [ ], 1716 | "type" : { 1717 | "kind" : "NON_NULL", 1718 | "name" : null, 1719 | "ofType" : { 1720 | "kind" : "LIST", 1721 | "name" : null, 1722 | "ofType" : { 1723 | "kind" : "NON_NULL", 1724 | "name" : null, 1725 | "ofType" : { 1726 | "kind" : "OBJECT", 1727 | "name" : "__InputValue", 1728 | "ofType" : null 1729 | } 1730 | } 1731 | } 1732 | }, 1733 | "isDeprecated" : false, 1734 | "deprecationReason" : null 1735 | }, { 1736 | "name" : "type", 1737 | "description" : null, 1738 | "args" : [ ], 1739 | "type" : { 1740 | "kind" : "NON_NULL", 1741 | "name" : null, 1742 | "ofType" : { 1743 | "kind" : "OBJECT", 1744 | "name" : "__Type", 1745 | "ofType" : null 1746 | } 1747 | }, 1748 | "isDeprecated" : false, 1749 | "deprecationReason" : null 1750 | }, { 1751 | "name" : "isDeprecated", 1752 | "description" : null, 1753 | "args" : [ ], 1754 | "type" : { 1755 | "kind" : "NON_NULL", 1756 | "name" : null, 1757 | "ofType" : { 1758 | "kind" : "SCALAR", 1759 | "name" : "Boolean", 1760 | "ofType" : null 1761 | } 1762 | }, 1763 | "isDeprecated" : false, 1764 | "deprecationReason" : null 1765 | }, { 1766 | "name" : "deprecationReason", 1767 | "description" : null, 1768 | "args" : [ ], 1769 | "type" : { 1770 | "kind" : "SCALAR", 1771 | "name" : "String", 1772 | "ofType" : null 1773 | }, 1774 | "isDeprecated" : false, 1775 | "deprecationReason" : null 1776 | } ], 1777 | "inputFields" : null, 1778 | "interfaces" : [ ], 1779 | "enumValues" : null, 1780 | "possibleTypes" : null 1781 | }, { 1782 | "kind" : "OBJECT", 1783 | "name" : "__InputValue", 1784 | "description" : null, 1785 | "fields" : [ { 1786 | "name" : "name", 1787 | "description" : null, 1788 | "args" : [ ], 1789 | "type" : { 1790 | "kind" : "NON_NULL", 1791 | "name" : null, 1792 | "ofType" : { 1793 | "kind" : "SCALAR", 1794 | "name" : "String", 1795 | "ofType" : null 1796 | } 1797 | }, 1798 | "isDeprecated" : false, 1799 | "deprecationReason" : null 1800 | }, { 1801 | "name" : "description", 1802 | "description" : null, 1803 | "args" : [ ], 1804 | "type" : { 1805 | "kind" : "SCALAR", 1806 | "name" : "String", 1807 | "ofType" : null 1808 | }, 1809 | "isDeprecated" : false, 1810 | "deprecationReason" : null 1811 | }, { 1812 | "name" : "type", 1813 | "description" : null, 1814 | "args" : [ ], 1815 | "type" : { 1816 | "kind" : "NON_NULL", 1817 | "name" : null, 1818 | "ofType" : { 1819 | "kind" : "OBJECT", 1820 | "name" : "__Type", 1821 | "ofType" : null 1822 | } 1823 | }, 1824 | "isDeprecated" : false, 1825 | "deprecationReason" : null 1826 | }, { 1827 | "name" : "defaultValue", 1828 | "description" : null, 1829 | "args" : [ ], 1830 | "type" : { 1831 | "kind" : "SCALAR", 1832 | "name" : "String", 1833 | "ofType" : null 1834 | }, 1835 | "isDeprecated" : false, 1836 | "deprecationReason" : null 1837 | } ], 1838 | "inputFields" : null, 1839 | "interfaces" : [ ], 1840 | "enumValues" : null, 1841 | "possibleTypes" : null 1842 | }, { 1843 | "kind" : "OBJECT", 1844 | "name" : "__EnumValue", 1845 | "description" : null, 1846 | "fields" : [ { 1847 | "name" : "name", 1848 | "description" : null, 1849 | "args" : [ ], 1850 | "type" : { 1851 | "kind" : "NON_NULL", 1852 | "name" : null, 1853 | "ofType" : { 1854 | "kind" : "SCALAR", 1855 | "name" : "String", 1856 | "ofType" : null 1857 | } 1858 | }, 1859 | "isDeprecated" : false, 1860 | "deprecationReason" : null 1861 | }, { 1862 | "name" : "description", 1863 | "description" : null, 1864 | "args" : [ ], 1865 | "type" : { 1866 | "kind" : "SCALAR", 1867 | "name" : "String", 1868 | "ofType" : null 1869 | }, 1870 | "isDeprecated" : false, 1871 | "deprecationReason" : null 1872 | }, { 1873 | "name" : "isDeprecated", 1874 | "description" : null, 1875 | "args" : [ ], 1876 | "type" : { 1877 | "kind" : "NON_NULL", 1878 | "name" : null, 1879 | "ofType" : { 1880 | "kind" : "SCALAR", 1881 | "name" : "Boolean", 1882 | "ofType" : null 1883 | } 1884 | }, 1885 | "isDeprecated" : false, 1886 | "deprecationReason" : null 1887 | }, { 1888 | "name" : "deprecationReason", 1889 | "description" : null, 1890 | "args" : [ ], 1891 | "type" : { 1892 | "kind" : "SCALAR", 1893 | "name" : "String", 1894 | "ofType" : null 1895 | }, 1896 | "isDeprecated" : false, 1897 | "deprecationReason" : null 1898 | } ], 1899 | "inputFields" : null, 1900 | "interfaces" : [ ], 1901 | "enumValues" : null, 1902 | "possibleTypes" : null 1903 | }, { 1904 | "kind" : "OBJECT", 1905 | "name" : "__Directive", 1906 | "description" : null, 1907 | "fields" : [ { 1908 | "name" : "name", 1909 | "description" : null, 1910 | "args" : [ ], 1911 | "type" : { 1912 | "kind" : "SCALAR", 1913 | "name" : "String", 1914 | "ofType" : null 1915 | }, 1916 | "isDeprecated" : false, 1917 | "deprecationReason" : null 1918 | }, { 1919 | "name" : "description", 1920 | "description" : null, 1921 | "args" : [ ], 1922 | "type" : { 1923 | "kind" : "SCALAR", 1924 | "name" : "String", 1925 | "ofType" : null 1926 | }, 1927 | "isDeprecated" : false, 1928 | "deprecationReason" : null 1929 | }, { 1930 | "name" : "locations", 1931 | "description" : null, 1932 | "args" : [ ], 1933 | "type" : { 1934 | "kind" : "LIST", 1935 | "name" : null, 1936 | "ofType" : { 1937 | "kind" : "NON_NULL", 1938 | "name" : null, 1939 | "ofType" : { 1940 | "kind" : "ENUM", 1941 | "name" : "__DirectiveLocation", 1942 | "ofType" : null 1943 | } 1944 | } 1945 | }, 1946 | "isDeprecated" : false, 1947 | "deprecationReason" : null 1948 | }, { 1949 | "name" : "args", 1950 | "description" : null, 1951 | "args" : [ ], 1952 | "type" : { 1953 | "kind" : "NON_NULL", 1954 | "name" : null, 1955 | "ofType" : { 1956 | "kind" : "LIST", 1957 | "name" : null, 1958 | "ofType" : { 1959 | "kind" : "NON_NULL", 1960 | "name" : null, 1961 | "ofType" : { 1962 | "kind" : "OBJECT", 1963 | "name" : "__InputValue", 1964 | "ofType" : null 1965 | } 1966 | } 1967 | } 1968 | }, 1969 | "isDeprecated" : false, 1970 | "deprecationReason" : null 1971 | }, { 1972 | "name" : "onOperation", 1973 | "description" : null, 1974 | "args" : [ ], 1975 | "type" : { 1976 | "kind" : "SCALAR", 1977 | "name" : "Boolean", 1978 | "ofType" : null 1979 | }, 1980 | "isDeprecated" : true, 1981 | "deprecationReason" : "Use `locations`." 1982 | }, { 1983 | "name" : "onFragment", 1984 | "description" : null, 1985 | "args" : [ ], 1986 | "type" : { 1987 | "kind" : "SCALAR", 1988 | "name" : "Boolean", 1989 | "ofType" : null 1990 | }, 1991 | "isDeprecated" : true, 1992 | "deprecationReason" : "Use `locations`." 1993 | }, { 1994 | "name" : "onField", 1995 | "description" : null, 1996 | "args" : [ ], 1997 | "type" : { 1998 | "kind" : "SCALAR", 1999 | "name" : "Boolean", 2000 | "ofType" : null 2001 | }, 2002 | "isDeprecated" : true, 2003 | "deprecationReason" : "Use `locations`." 2004 | } ], 2005 | "inputFields" : null, 2006 | "interfaces" : [ ], 2007 | "enumValues" : null, 2008 | "possibleTypes" : null 2009 | }, { 2010 | "kind" : "ENUM", 2011 | "name" : "__DirectiveLocation", 2012 | "description" : "An enum describing valid locations where a directive can be placed", 2013 | "fields" : null, 2014 | "inputFields" : null, 2015 | "interfaces" : null, 2016 | "enumValues" : [ { 2017 | "name" : "QUERY", 2018 | "description" : "Indicates the directive is valid on queries.", 2019 | "isDeprecated" : false, 2020 | "deprecationReason" : null 2021 | }, { 2022 | "name" : "MUTATION", 2023 | "description" : "Indicates the directive is valid on mutations.", 2024 | "isDeprecated" : false, 2025 | "deprecationReason" : null 2026 | }, { 2027 | "name" : "FIELD", 2028 | "description" : "Indicates the directive is valid on fields.", 2029 | "isDeprecated" : false, 2030 | "deprecationReason" : null 2031 | }, { 2032 | "name" : "FRAGMENT_DEFINITION", 2033 | "description" : "Indicates the directive is valid on fragment definitions.", 2034 | "isDeprecated" : false, 2035 | "deprecationReason" : null 2036 | }, { 2037 | "name" : "FRAGMENT_SPREAD", 2038 | "description" : "Indicates the directive is valid on fragment spreads.", 2039 | "isDeprecated" : false, 2040 | "deprecationReason" : null 2041 | }, { 2042 | "name" : "INLINE_FRAGMENT", 2043 | "description" : "Indicates the directive is valid on inline fragments.", 2044 | "isDeprecated" : false, 2045 | "deprecationReason" : null 2046 | }, { 2047 | "name" : "SCHEMA", 2048 | "description" : "Indicates the directive is valid on a schema SDL definition.", 2049 | "isDeprecated" : false, 2050 | "deprecationReason" : null 2051 | }, { 2052 | "name" : "SCALAR", 2053 | "description" : "Indicates the directive is valid on a scalar SDL definition.", 2054 | "isDeprecated" : false, 2055 | "deprecationReason" : null 2056 | }, { 2057 | "name" : "OBJECT", 2058 | "description" : "Indicates the directive is valid on an object SDL definition.", 2059 | "isDeprecated" : false, 2060 | "deprecationReason" : null 2061 | }, { 2062 | "name" : "FIELD_DEFINITION", 2063 | "description" : "Indicates the directive is valid on a field SDL definition.", 2064 | "isDeprecated" : false, 2065 | "deprecationReason" : null 2066 | }, { 2067 | "name" : "ARGUMENT_DEFINITION", 2068 | "description" : "Indicates the directive is valid on a field argument SDL definition.", 2069 | "isDeprecated" : false, 2070 | "deprecationReason" : null 2071 | }, { 2072 | "name" : "INTERFACE", 2073 | "description" : "Indicates the directive is valid on an interface SDL definition.", 2074 | "isDeprecated" : false, 2075 | "deprecationReason" : null 2076 | }, { 2077 | "name" : "UNION", 2078 | "description" : "Indicates the directive is valid on an union SDL definition.", 2079 | "isDeprecated" : false, 2080 | "deprecationReason" : null 2081 | }, { 2082 | "name" : "ENUM", 2083 | "description" : "Indicates the directive is valid on an enum SDL definition.", 2084 | "isDeprecated" : false, 2085 | "deprecationReason" : null 2086 | }, { 2087 | "name" : "ENUM_VALUE", 2088 | "description" : "Indicates the directive is valid on an enum value SDL definition.", 2089 | "isDeprecated" : false, 2090 | "deprecationReason" : null 2091 | }, { 2092 | "name" : "INPUT_OBJECT", 2093 | "description" : "Indicates the directive is valid on an input object SDL definition.", 2094 | "isDeprecated" : false, 2095 | "deprecationReason" : null 2096 | }, { 2097 | "name" : "INPUT_FIELD_DEFINITION", 2098 | "description" : "Indicates the directive is valid on an input object field SDL definition.", 2099 | "isDeprecated" : false, 2100 | "deprecationReason" : null 2101 | } ], 2102 | "possibleTypes" : null 2103 | } ], 2104 | "directives" : [ { 2105 | "name" : "include", 2106 | "description" : "Directs the executor to include this field or fragment only when the `if` argument is true", 2107 | "locations" : [ "FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT" ], 2108 | "args" : [ { 2109 | "name" : "if", 2110 | "description" : "Included when true.", 2111 | "type" : { 2112 | "kind" : "NON_NULL", 2113 | "name" : null, 2114 | "ofType" : { 2115 | "kind" : "SCALAR", 2116 | "name" : "Boolean", 2117 | "ofType" : null 2118 | } 2119 | }, 2120 | "defaultValue" : null 2121 | } ], 2122 | "onOperation" : false, 2123 | "onFragment" : true, 2124 | "onField" : true 2125 | }, { 2126 | "name" : "skip", 2127 | "description" : "Directs the executor to skip this field or fragment when the `if`'argument is true.", 2128 | "locations" : [ "FIELD", "FRAGMENT_SPREAD", "INLINE_FRAGMENT" ], 2129 | "args" : [ { 2130 | "name" : "if", 2131 | "description" : "Skipped when true.", 2132 | "type" : { 2133 | "kind" : "NON_NULL", 2134 | "name" : null, 2135 | "ofType" : { 2136 | "kind" : "SCALAR", 2137 | "name" : "Boolean", 2138 | "ofType" : null 2139 | } 2140 | }, 2141 | "defaultValue" : null 2142 | } ], 2143 | "onOperation" : false, 2144 | "onFragment" : true, 2145 | "onField" : true 2146 | }, { 2147 | "name" : "defer", 2148 | "description" : "This directive allows results to be deferred during execution", 2149 | "locations" : [ "FIELD" ], 2150 | "args" : [ ], 2151 | "onOperation" : false, 2152 | "onFragment" : false, 2153 | "onField" : true 2154 | }, { 2155 | "name" : "aws_publish", 2156 | "description" : "Tells the service which subscriptions will be published to when this mutation is called. This directive is deprecated use @aws_susbscribe directive instead.", 2157 | "locations" : [ "FIELD_DEFINITION" ], 2158 | "args" : [ { 2159 | "name" : "subscriptions", 2160 | "description" : "List of subscriptions which will be published to when this mutation is called.", 2161 | "type" : { 2162 | "kind" : "LIST", 2163 | "name" : null, 2164 | "ofType" : { 2165 | "kind" : "SCALAR", 2166 | "name" : "String", 2167 | "ofType" : null 2168 | } 2169 | }, 2170 | "defaultValue" : null 2171 | } ], 2172 | "onOperation" : false, 2173 | "onFragment" : false, 2174 | "onField" : false 2175 | }, { 2176 | "name" : "aws_api_key", 2177 | "description" : "Tells the service this field/object has access authorized by an API key.", 2178 | "locations" : [ "OBJECT", "FIELD_DEFINITION" ], 2179 | "args" : [ ], 2180 | "onOperation" : false, 2181 | "onFragment" : false, 2182 | "onField" : false 2183 | }, { 2184 | "name" : "aws_auth", 2185 | "description" : "Directs the schema to enforce authorization on a field", 2186 | "locations" : [ "FIELD_DEFINITION" ], 2187 | "args" : [ { 2188 | "name" : "cognito_groups", 2189 | "description" : "List of cognito user pool groups which have access on this field", 2190 | "type" : { 2191 | "kind" : "LIST", 2192 | "name" : null, 2193 | "ofType" : { 2194 | "kind" : "SCALAR", 2195 | "name" : "String", 2196 | "ofType" : null 2197 | } 2198 | }, 2199 | "defaultValue" : null 2200 | } ], 2201 | "onOperation" : false, 2202 | "onFragment" : false, 2203 | "onField" : false 2204 | }, { 2205 | "name" : "aws_iam", 2206 | "description" : "Tells the service this field/object has access authorized by sigv4 signing.", 2207 | "locations" : [ "OBJECT", "FIELD_DEFINITION" ], 2208 | "args" : [ ], 2209 | "onOperation" : false, 2210 | "onFragment" : false, 2211 | "onField" : false 2212 | }, { 2213 | "name" : "aws_subscribe", 2214 | "description" : "Tells the service which mutation triggers this subscription.", 2215 | "locations" : [ "FIELD_DEFINITION" ], 2216 | "args" : [ { 2217 | "name" : "mutations", 2218 | "description" : "List of mutations which will trigger this subscription when they are called.", 2219 | "type" : { 2220 | "kind" : "LIST", 2221 | "name" : null, 2222 | "ofType" : { 2223 | "kind" : "SCALAR", 2224 | "name" : "String", 2225 | "ofType" : null 2226 | } 2227 | }, 2228 | "defaultValue" : null 2229 | } ], 2230 | "onOperation" : false, 2231 | "onFragment" : false, 2232 | "onField" : false 2233 | }, { 2234 | "name" : "deprecated", 2235 | "description" : null, 2236 | "locations" : [ "FIELD_DEFINITION", "ENUM_VALUE" ], 2237 | "args" : [ { 2238 | "name" : "reason", 2239 | "description" : null, 2240 | "type" : { 2241 | "kind" : "SCALAR", 2242 | "name" : "String", 2243 | "ofType" : null 2244 | }, 2245 | "defaultValue" : "\"No longer supported\"" 2246 | } ], 2247 | "onOperation" : false, 2248 | "onFragment" : false, 2249 | "onField" : false 2250 | }, { 2251 | "name" : "aws_cognito_user_pools", 2252 | "description" : "Tells the service this field/object has access authorized by a Cognito User Pools token.", 2253 | "locations" : [ "OBJECT", "FIELD_DEFINITION" ], 2254 | "args" : [ { 2255 | "name" : "cognito_groups", 2256 | "description" : "List of cognito user pool groups which have access on this field", 2257 | "type" : { 2258 | "kind" : "LIST", 2259 | "name" : null, 2260 | "ofType" : { 2261 | "kind" : "SCALAR", 2262 | "name" : "String", 2263 | "ofType" : null 2264 | } 2265 | }, 2266 | "defaultValue" : null 2267 | } ], 2268 | "onOperation" : false, 2269 | "onFragment" : false, 2270 | "onField" : false 2271 | }, { 2272 | "name" : "aws_oidc", 2273 | "description" : "Tells the service this field/object has access authorized by an OIDC token.", 2274 | "locations" : [ "OBJECT", "FIELD_DEFINITION" ], 2275 | "args" : [ ], 2276 | "onOperation" : false, 2277 | "onFragment" : false, 2278 | "onField" : false 2279 | } ] 2280 | } 2281 | } 2282 | } --------------------------------------------------------------------------------