├── .gitignore ├── README.md ├── blogPart1.txt ├── blogPart2.txt ├── channel.sql ├── golang ├── .realize.yaml ├── app │ ├── config │ │ ├── connection │ │ │ └── connection.go │ │ ├── constants │ │ │ └── constants.go │ │ └── database │ │ │ └── database.go │ ├── graph │ │ └── generated.go │ ├── model │ │ └── models_gen.go │ └── resolver │ │ ├── ChannelResolver.go │ │ └── resolver.go ├── gqlgen.yml ├── main.go └── schema.graphql └── reactjs ├── package.json ├── public ├── css │ ├── bootstrap.min.css │ ├── dataTables.bootstrap4.min.css │ ├── datatables.min.css │ └── loader.css ├── img │ ├── 3pl-logo-600.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── green.png │ ├── red.png │ ├── yellow.jpg │ └── yellow.png ├── index.html └── js │ ├── bootstrap.min.js │ ├── dataTables.bootstrap4.min.js │ ├── datatables.min.js │ ├── jquery-3.2.1.min.js │ ├── jquery.dataTables.min.js │ └── jquery.validate.min.js └── src ├── App.jsx ├── components └── ChannelList │ ├── ChannelList.css │ └── ChannelList.jsx ├── environment.jsx ├── index.js └── style └── app.scss /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | reactjs/node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | package-lock.json 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 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Golang-gqlgen-Reactjs-subscription-demo 2 | 3 | You can find step by step guide for Golang Part 1 [here](https://www.logisticinfotech.com/blog/graphql-subscription-golang-reactjs/) And React Part 2 [here](https://www.logisticinfotech.com/blog/react-apollo-client-subscription/) to understand this demo properly. 4 | 5 | for golang graphql gqlgen package is used. 6 | for reacjs applo-client is used. 7 | 8 | ## Preview 9 | ![](https://www.logisticinfotech.com/wp-content/uploads/2018/09/golang-react-subscription.gif) 10 | 11 | ## How to Run 12 | ``` 13 | cd golang 14 | go get ./ 15 | go run main.go 16 | 17 | cd reactjs 18 | npm install 19 | npm start 20 | 21 | ``` 22 | 23 | Golang graphql server will start on 24 | http://localhost:8888 25 | 26 | React server will start on 27 | http://localhost:3000 28 | 29 | 30 | 31 | ## Further help 32 | 33 | Checkout full blog for Golang Part 1 [here](https://www.logisticinfotech.com/blog/graphql-subscription-golang-reactjs/) And React Part 2 [here](https://www.logisticinfotech.com/blog/react-apollo-client-subscription/) 34 | -------------------------------------------------------------------------------- /blogPart1.txt: -------------------------------------------------------------------------------- 1 | For this demo we have used golang gqlgen package, mysql and reactjs apollo-client. 2 | For better understanding we have used mysql for database. 3 | Purpose of this demo is to showcase graphql query, mutation and subscription in golang. 4 | Although gqlgen original documantation is good but I thought its best to do CRUD saperatly for learning purpose. 5 | I hope this will great help to someone starting golang graphql. 6 | I am considering reader has little knowledge of golang and database connection in golang 7 | 8 | This is part1 of two searies tutorial 9 | 1. golang gqlgen backend 10 | 2. reactjs apollo-client front end which using this golang backend. 11 | 12 | what is gqlgen? 13 | Its golang package cum utility which allows us to auto generate golang code stub from graphql schema automatically. 14 | Their original getting started is good to read but I will mention steps here also. 15 | 16 | Step 1 : 17 | > Install gqlgen 18 | $ go get -u github.com/99designs/gqlgen github.com/vektah/gorunpkg 19 | 20 | > All the code we will be doing should reside in go/src folder. 21 | So purpose of this demo 22 | ~/go/src/golang-gqlgen-reactjs-subscription-demo/golang 23 | this is preferred path. 24 | 25 | 26 | Step 2: 27 | so first we need to create our required graphql schema. 28 | 29 | Create schema.graphql file with below: 30 | type Channel { 31 | id: Int! # "!" denotes a required field 32 | name: String! 33 | } 34 | 35 | type Query { 36 | channels: [Channel!]! 37 | } 38 | 39 | type Mutation { 40 | addChannel(name: String!): Channel! 41 | updateChannel(id:Int!,name: String!): Channel! 42 | deleteChannel(ID: Int!): Channel! 43 | } 44 | 45 | type Subscription { 46 | subscriptionChannelAdded: Channel! 47 | subscriptionChannelDeleted: Channel! 48 | subscriptionChannelUpdated: Channel! 49 | } 50 | 51 | then next file we need is gqlgen.yml 52 | this file is responsible to direct gqlgen where to autogenerate files. 53 | 54 | for our demo purpose content will be as below 55 | schema: schema.graphql 56 | exec: 57 | filename: app/graph/generated.go 58 | 59 | model: 60 | filename: app/model/models_gen.go 61 | 62 | resolver: 63 | filename: app/resolver/resolver.go 64 | type: Resolver 65 | 66 | Step 3: 67 | inside our mentioned folder fire command 68 | $ gqlgen 69 | 70 | this will generate below files if you are first time running it. 71 | 72 | app/graph/generated.go 73 | app/model/models_gen.go 74 | app/resolver/resolver.go (if this file exists it will not be regenrated) 75 | 76 | Step 4: 77 | So first thing will require for us is graphql query to get all channels. 78 | 79 | As we have followed little different structure for ease of understanding and maintanance. 80 | Create file app/resolver/ChannelResolver.go 81 | 82 | func (r *queryResolver) Channels(ctx context.Context) ([]model.Channel, error) { 83 | db := connection.DbConn() 84 | var query = "SELECT * FROM channel" 85 | selDB, err := db.Query(query) 86 | var arrChannel []model.Channel 87 | for selDB.Next() { 88 | var name string 89 | var id int64 90 | err = selDB.Scan(&id, &name) 91 | if err != nil { 92 | panic(err.Error()) 93 | } 94 | todo1 := model.Channel{ID: int(id), Name: name} 95 | arrChannel = append(arrChannel, todo1) 96 | } 97 | 98 | defer db.Close() 99 | return arrChannel, nil 100 | } 101 | 102 | dont forget to remove below funciton from resolver.go file 103 | Channels(ctx context.Context) ([]model.Channel, error) 104 | 105 | For now we will consontrate only on Add Channel Mutation and Subscription 106 | (although we have included Edit/Delete Channels mutation and subscription) 107 | 108 | For subscription we need to create one observer for our channel list 109 | var addChannelObserver map[string]chan model.Channel 110 | 111 | Now in ChannelResolver.go init we set blank model.Channel Object in addChannelObserver 112 | func init() { 113 | addChannelObserver = map[string]chan model.Channel{} 114 | } 115 | 116 | When any new channel added we need to add newly added channel into our addChannelObserver 117 | 118 | func (r *mutationResolver) AddChannel(ctx context.Context, name string) (model.Channel, error) { 119 | db := connection.DbConn() 120 | 121 | insForm, err := db.Prepare("INSERT INTO channel(name) VALUES(?)") 122 | if err != nil { 123 | panic(err.Error()) 124 | } 125 | 126 | var newChannel model.Channel 127 | res, err := insForm.Exec(name) 128 | if err != nil { 129 | println("Exec err:", err.Error()) 130 | } else { 131 | var id int64 132 | id, err := res.LastInsertId() 133 | if err != nil { 134 | println("Error:", err.Error()) 135 | } else { 136 | newChannel = model.Channel{ID: int(id), Name: name} 137 | } 138 | } 139 | defer db.Close() 140 | // Add new chanel in addChannelObserver 141 | for _, observer := range addChannelObserver { 142 | observer <- newChannel 143 | } 144 | return newChannel, nil 145 | } 146 | 147 | Now we will create function to fire subscription for channelAdded 148 | 149 | func (r *subscriptionResolver) SubscriptionChannelAdded(ctx context.Context) (<-chan model.Channel, error) { 150 | id := randString(8) 151 | events := make(chan model.Channel, 1) 152 | 153 | go func() { 154 | <-ctx.Done() 155 | delete(addChannelObserver, id) 156 | }() 157 | 158 | addChannelObserver[id] = events 159 | 160 | return events, nil 161 | } 162 | 163 | We can run this code with 164 | $ go run main.go 165 | 166 | and url will be http://localhost:8888 167 | 168 | That is all for golang code 169 | -------------------------------------------------------------------------------- /blogPart2.txt: -------------------------------------------------------------------------------- 1 | This is a second part of reactjs apollo-client front end in which as backend we have used golang gqlgen graphql server 2 | Here also I am assuming readers know reactjs little bit. 3 | 4 | For this demo again preferred path is 5 | ~/go/src/golang-gqlgen-reactjs-subscription-demo/reactjs 6 | 7 | Step 1 : 8 | you can start react project with default create-react-app 9 | 10 | First of all we need to connect our front-end with back end 11 | So we have used ApolloClient for connection to golang backend 12 | 13 | const wsLink = new WebSocketLink({ 14 | uri: environment.WSHost, 15 | options: { 16 | reconnect: true 17 | } 18 | }); 19 | const apolloClient = new ApolloClient({ 20 | link: wsLink, 21 | cache: new InMemoryCache(), 22 | }); 23 | 24 | function render(component) { 25 | ReactDOM.render( 26 | {component} 27 | , document.getElementById('root')); 28 | } 29 | 30 | render(); 31 | 32 | Step 2: 33 | Create component for CURD operation of channel 34 | for that we will create file reactjs/src/components/ChannelList.jsx 35 | 36 | Okay so we will try to understand devide this file in few section to understand easily 37 | 1) Import section we need to insert react-apollo and graphql-tag for call graphql Query and Mutation 38 | import React, { Component } from 'react'; 39 | import { graphql, Mutation, compose } from 'react-apollo'; 40 | import gql from 'graphql-tag'; 41 | 42 | 2) Render of react component 43 | class ChannelsList extends Component { 44 | componentWillMount() { 45 | // Add subscribeToMore method for watch subscription of add channel 46 | this.props.data.subscribeToMore({ 47 | document: addChannelSubscription, // Use the subscription 48 | updateQuery: (prev, { subscriptionData }) => { 49 | if (!subscriptionData.data) { 50 | return prev; 51 | } 52 | const newChannel = subscriptionData.data.subscriptionChannelAdded; 53 | // Add check to prevent double adding of channels. 54 | if (!prev.channels.find((channel) => channel.id === newChannel.id)) { 55 | let updatedChannels = Object.assign({}, prev, { channels: [...prev.channels, newChannel] }); 56 | return updatedChannels; 57 | } else { 58 | return prev; 59 | } 60 | } 61 | }); 62 | } 63 | 64 | render() { 65 | // we get data of channels on page render from props 66 | const { data: { loading, error, channels } } = this.props; 67 | if (loading) { 68 | return

Loading ...

; 69 | } 70 | if (error) { 71 | return

{error.message}

; 72 | } 73 | 74 | return ( 75 |
76 |
77 |
78 |

Channel List

79 |
80 |
81 | 88 |
89 | 107 |
108 |
109 |
110 | ) 111 | } 112 | } 113 | 114 | 3) Now Write Query ,Mutation and Subscription for CRUD channel 115 | // query for get all channel list 116 | export const channelsListQuery = gql` 117 | query ChannelsListQuery { 118 | channels { 119 | id 120 | name 121 | } 122 | } 123 | `; 124 | 125 | //Mutation for add channel 126 | const CreateChannelMutation = gql` 127 | mutation addChannel($name: String!) { 128 | addChannel(name: $name) { 129 | id 130 | name 131 | } 132 | } 133 | `; 134 | 135 | //Subscription for newly added channel 136 | 137 | const addChannelSubscription = gql` 138 | subscription Channels { 139 | subscriptionChannelAdded { 140 | id 141 | name 142 | } 143 | } 144 | ` 145 | 146 | //export class with graphql query and mutation is very import for get data on component load 147 | 148 | const multipleMutation = compose( 149 | graphql(CreateChannelMutation, { name: 'createChannelMutation' }) 150 | ) 151 | export default compose(multipleMutation, graphql(channelsListQuery))(ChannelsList); 152 | -------------------------------------------------------------------------------- /channel.sql: -------------------------------------------------------------------------------- 1 | -- phpMyAdmin SQL Dump 2 | -- version 4.5.4.1deb2ubuntu2 3 | -- http://www.phpmyadmin.net 4 | -- 5 | -- Host: localhost 6 | -- Generation Time: Sep 13, 2018 at 05:12 PM 7 | -- Server version: 5.7.19-0ubuntu0.16.04.1 8 | -- PHP Version: 7.0.22-0ubuntu0.16.04.1 9 | 10 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 11 | 12 | 13 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 14 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 15 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 16 | /*!40101 SET NAMES utf8mb4 */; 17 | 18 | -- 19 | -- Database: `gqlgenreact` 20 | -- 21 | 22 | -- -------------------------------------------------------- 23 | 24 | -- 25 | -- Table structure for table `channel` 26 | -- 27 | 28 | CREATE TABLE `channel` ( 29 | `id` int(11) NOT NULL, 30 | `name` varchar(255) NOT NULL 31 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 32 | 33 | -- 34 | -- Indexes for dumped tables 35 | -- 36 | 37 | -- 38 | -- Indexes for table `channel` 39 | -- 40 | ALTER TABLE `channel` 41 | ADD PRIMARY KEY (`id`); 42 | 43 | -- 44 | -- AUTO_INCREMENT for dumped tables 45 | -- 46 | 47 | -- 48 | -- AUTO_INCREMENT for table `channel` 49 | -- 50 | ALTER TABLE `channel` 51 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT; 52 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 53 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 54 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 55 | -------------------------------------------------------------------------------- /golang/.realize.yaml: -------------------------------------------------------------------------------- 1 | settings: 2 | legacy: 3 | force: false 4 | interval: 0s 5 | schema: 6 | - name: gqlgen_demo 7 | path: . 8 | commands: 9 | run: 10 | status: true 11 | watcher: 12 | extensions: 13 | - go 14 | paths: 15 | - / 16 | ignored_paths: 17 | - .git 18 | - .realize 19 | - vendor 20 | -------------------------------------------------------------------------------- /golang/app/config/connection/connection.go: -------------------------------------------------------------------------------- 1 | package connection 2 | 3 | import ( 4 | "database/sql" 5 | "lidemo/gqlgenreact/golang/app/config/constants" 6 | 7 | _ "github.com/go-sql-driver/mysql" 8 | ) 9 | 10 | func DbConn() (db *sql.DB) { 11 | dbDriver := "mysql" 12 | dbUser := constants.DBUSER 13 | dbPass := constants.DBPASSWORD 14 | dbHost := constants.DBHOST 15 | dbPort := constants.DBPORT 16 | dbName := constants.DBNAME 17 | db, err := sql.Open(dbDriver, dbUser+":"+dbPass+"@tcp("+dbHost+":"+dbPort+")/"+dbName+"?parseTime=true") 18 | if err != nil { 19 | panic(err.Error()) 20 | } 21 | return db 22 | } 23 | -------------------------------------------------------------------------------- /golang/app/config/constants/constants.go: -------------------------------------------------------------------------------- 1 | package constants 2 | 3 | const ( 4 | DBUSER = "gqlgenreact" 5 | DBPASSWORD = "gqlgenreact" 6 | DBHOST = "192.168.0.77" 7 | DBPORT = "3306" 8 | DBNAME = "gqlgenreact" 9 | ) 10 | -------------------------------------------------------------------------------- /golang/app/config/database/database.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | import "github.com/jinzhu/gorm" 4 | 5 | var ( 6 | // DBCon is the connection handle 7 | // for the database 8 | DBCon *gorm.DB 9 | ) 10 | -------------------------------------------------------------------------------- /golang/app/graph/generated.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT. 2 | 3 | package graph 4 | 5 | import ( 6 | "bytes" 7 | context "context" 8 | model "golang-gqlgen-reactjs-subscription-demo/golang/app/model" 9 | strconv "strconv" 10 | sync "sync" 11 | 12 | graphql "github.com/99designs/gqlgen/graphql" 13 | introspection "github.com/99designs/gqlgen/graphql/introspection" 14 | gqlparser "github.com/vektah/gqlparser" 15 | ast "github.com/vektah/gqlparser/ast" 16 | ) 17 | 18 | // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. 19 | func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { 20 | return &executableSchema{ 21 | resolvers: cfg.Resolvers, 22 | directives: cfg.Directives, 23 | complexity: cfg.Complexity, 24 | } 25 | } 26 | 27 | type Config struct { 28 | Resolvers ResolverRoot 29 | Directives DirectiveRoot 30 | Complexity ComplexityRoot 31 | } 32 | 33 | type ResolverRoot interface { 34 | Mutation() MutationResolver 35 | Query() QueryResolver 36 | Subscription() SubscriptionResolver 37 | } 38 | 39 | type DirectiveRoot struct { 40 | } 41 | 42 | type ComplexityRoot struct { 43 | Channel struct { 44 | Id func(childComplexity int) int 45 | Name func(childComplexity int) int 46 | } 47 | 48 | Mutation struct { 49 | AddChannel func(childComplexity int, name string) int 50 | UpdateChannel func(childComplexity int, id int, name string) int 51 | DeleteChannel func(childComplexity int, ID int) int 52 | } 53 | 54 | Query struct { 55 | Channels func(childComplexity int) int 56 | } 57 | 58 | Subscription struct { 59 | SubscriptionChannelAdded func(childComplexity int) int 60 | SubscriptionChannelDeleted func(childComplexity int) int 61 | SubscriptionChannelUpdated func(childComplexity int) int 62 | } 63 | } 64 | 65 | type MutationResolver interface { 66 | AddChannel(ctx context.Context, name string) (model.Channel, error) 67 | UpdateChannel(ctx context.Context, id int, name string) (model.Channel, error) 68 | DeleteChannel(ctx context.Context, ID int) (model.Channel, error) 69 | } 70 | type QueryResolver interface { 71 | Channels(ctx context.Context) ([]model.Channel, error) 72 | } 73 | type SubscriptionResolver interface { 74 | SubscriptionChannelAdded(ctx context.Context) (<-chan model.Channel, error) 75 | SubscriptionChannelDeleted(ctx context.Context) (<-chan model.Channel, error) 76 | SubscriptionChannelUpdated(ctx context.Context) (<-chan model.Channel, error) 77 | } 78 | 79 | func field_Mutation_addChannel_args(rawArgs map[string]interface{}) (map[string]interface{}, error) { 80 | args := map[string]interface{}{} 81 | var arg0 string 82 | if tmp, ok := rawArgs["name"]; ok { 83 | var err error 84 | arg0, err = graphql.UnmarshalString(tmp) 85 | if err != nil { 86 | return nil, err 87 | } 88 | } 89 | args["name"] = arg0 90 | return args, nil 91 | 92 | } 93 | 94 | func field_Mutation_updateChannel_args(rawArgs map[string]interface{}) (map[string]interface{}, error) { 95 | args := map[string]interface{}{} 96 | var arg0 int 97 | if tmp, ok := rawArgs["id"]; ok { 98 | var err error 99 | arg0, err = graphql.UnmarshalInt(tmp) 100 | if err != nil { 101 | return nil, err 102 | } 103 | } 104 | args["id"] = arg0 105 | var arg1 string 106 | if tmp, ok := rawArgs["name"]; ok { 107 | var err error 108 | arg1, err = graphql.UnmarshalString(tmp) 109 | if err != nil { 110 | return nil, err 111 | } 112 | } 113 | args["name"] = arg1 114 | return args, nil 115 | 116 | } 117 | 118 | func field_Mutation_deleteChannel_args(rawArgs map[string]interface{}) (map[string]interface{}, error) { 119 | args := map[string]interface{}{} 120 | var arg0 int 121 | if tmp, ok := rawArgs["ID"]; ok { 122 | var err error 123 | arg0, err = graphql.UnmarshalInt(tmp) 124 | if err != nil { 125 | return nil, err 126 | } 127 | } 128 | args["ID"] = arg0 129 | return args, nil 130 | 131 | } 132 | 133 | func field_Query___type_args(rawArgs map[string]interface{}) (map[string]interface{}, error) { 134 | args := map[string]interface{}{} 135 | var arg0 string 136 | if tmp, ok := rawArgs["name"]; ok { 137 | var err error 138 | arg0, err = graphql.UnmarshalString(tmp) 139 | if err != nil { 140 | return nil, err 141 | } 142 | } 143 | args["name"] = arg0 144 | return args, nil 145 | 146 | } 147 | 148 | func field___Type_fields_args(rawArgs map[string]interface{}) (map[string]interface{}, error) { 149 | args := map[string]interface{}{} 150 | var arg0 bool 151 | if tmp, ok := rawArgs["includeDeprecated"]; ok { 152 | var err error 153 | arg0, err = graphql.UnmarshalBoolean(tmp) 154 | if err != nil { 155 | return nil, err 156 | } 157 | } 158 | args["includeDeprecated"] = arg0 159 | return args, nil 160 | 161 | } 162 | 163 | func field___Type_enumValues_args(rawArgs map[string]interface{}) (map[string]interface{}, error) { 164 | args := map[string]interface{}{} 165 | var arg0 bool 166 | if tmp, ok := rawArgs["includeDeprecated"]; ok { 167 | var err error 168 | arg0, err = graphql.UnmarshalBoolean(tmp) 169 | if err != nil { 170 | return nil, err 171 | } 172 | } 173 | args["includeDeprecated"] = arg0 174 | return args, nil 175 | 176 | } 177 | 178 | type executableSchema struct { 179 | resolvers ResolverRoot 180 | directives DirectiveRoot 181 | complexity ComplexityRoot 182 | } 183 | 184 | func (e *executableSchema) Schema() *ast.Schema { 185 | return parsedSchema 186 | } 187 | 188 | func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) { 189 | switch typeName + "." + field { 190 | 191 | case "Channel.id": 192 | if e.complexity.Channel.Id == nil { 193 | break 194 | } 195 | 196 | return e.complexity.Channel.Id(childComplexity), true 197 | 198 | case "Channel.name": 199 | if e.complexity.Channel.Name == nil { 200 | break 201 | } 202 | 203 | return e.complexity.Channel.Name(childComplexity), true 204 | 205 | case "Mutation.addChannel": 206 | if e.complexity.Mutation.AddChannel == nil { 207 | break 208 | } 209 | 210 | args, err := field_Mutation_addChannel_args(rawArgs) 211 | if err != nil { 212 | return 0, false 213 | } 214 | 215 | return e.complexity.Mutation.AddChannel(childComplexity, args["name"].(string)), true 216 | 217 | case "Mutation.updateChannel": 218 | if e.complexity.Mutation.UpdateChannel == nil { 219 | break 220 | } 221 | 222 | args, err := field_Mutation_updateChannel_args(rawArgs) 223 | if err != nil { 224 | return 0, false 225 | } 226 | 227 | return e.complexity.Mutation.UpdateChannel(childComplexity, args["id"].(int), args["name"].(string)), true 228 | 229 | case "Mutation.deleteChannel": 230 | if e.complexity.Mutation.DeleteChannel == nil { 231 | break 232 | } 233 | 234 | args, err := field_Mutation_deleteChannel_args(rawArgs) 235 | if err != nil { 236 | return 0, false 237 | } 238 | 239 | return e.complexity.Mutation.DeleteChannel(childComplexity, args["ID"].(int)), true 240 | 241 | case "Query.channels": 242 | if e.complexity.Query.Channels == nil { 243 | break 244 | } 245 | 246 | return e.complexity.Query.Channels(childComplexity), true 247 | 248 | case "Subscription.subscriptionChannelAdded": 249 | if e.complexity.Subscription.SubscriptionChannelAdded == nil { 250 | break 251 | } 252 | 253 | return e.complexity.Subscription.SubscriptionChannelAdded(childComplexity), true 254 | 255 | case "Subscription.subscriptionChannelDeleted": 256 | if e.complexity.Subscription.SubscriptionChannelDeleted == nil { 257 | break 258 | } 259 | 260 | return e.complexity.Subscription.SubscriptionChannelDeleted(childComplexity), true 261 | 262 | case "Subscription.subscriptionChannelUpdated": 263 | if e.complexity.Subscription.SubscriptionChannelUpdated == nil { 264 | break 265 | } 266 | 267 | return e.complexity.Subscription.SubscriptionChannelUpdated(childComplexity), true 268 | 269 | } 270 | return 0, false 271 | } 272 | 273 | func (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinition) *graphql.Response { 274 | ec := executionContext{graphql.GetRequestContext(ctx), e} 275 | 276 | buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte { 277 | data := ec._Query(ctx, op.SelectionSet) 278 | var buf bytes.Buffer 279 | data.MarshalGQL(&buf) 280 | return buf.Bytes() 281 | }) 282 | 283 | return &graphql.Response{ 284 | Data: buf, 285 | Errors: ec.Errors, 286 | } 287 | } 288 | 289 | func (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefinition) *graphql.Response { 290 | ec := executionContext{graphql.GetRequestContext(ctx), e} 291 | 292 | buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte { 293 | data := ec._Mutation(ctx, op.SelectionSet) 294 | var buf bytes.Buffer 295 | data.MarshalGQL(&buf) 296 | return buf.Bytes() 297 | }) 298 | 299 | return &graphql.Response{ 300 | Data: buf, 301 | Errors: ec.Errors, 302 | } 303 | } 304 | 305 | func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDefinition) func() *graphql.Response { 306 | ec := executionContext{graphql.GetRequestContext(ctx), e} 307 | 308 | next := ec._Subscription(ctx, op.SelectionSet) 309 | if ec.Errors != nil { 310 | return graphql.OneShot(&graphql.Response{Data: []byte("null"), Errors: ec.Errors}) 311 | } 312 | 313 | var buf bytes.Buffer 314 | return func() *graphql.Response { 315 | buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte { 316 | buf.Reset() 317 | data := next() 318 | 319 | if data == nil { 320 | return nil 321 | } 322 | data.MarshalGQL(&buf) 323 | return buf.Bytes() 324 | }) 325 | 326 | return &graphql.Response{ 327 | Data: buf, 328 | Errors: ec.Errors, 329 | } 330 | } 331 | } 332 | 333 | type executionContext struct { 334 | *graphql.RequestContext 335 | *executableSchema 336 | } 337 | 338 | var channelImplementors = []string{"Channel"} 339 | 340 | // nolint: gocyclo, errcheck, gas, goconst 341 | func (ec *executionContext) _Channel(ctx context.Context, sel ast.SelectionSet, obj *model.Channel) graphql.Marshaler { 342 | fields := graphql.CollectFields(ctx, sel, channelImplementors) 343 | 344 | out := graphql.NewOrderedMap(len(fields)) 345 | invalid := false 346 | for i, field := range fields { 347 | out.Keys[i] = field.Alias 348 | 349 | switch field.Name { 350 | case "__typename": 351 | out.Values[i] = graphql.MarshalString("Channel") 352 | case "id": 353 | out.Values[i] = ec._Channel_id(ctx, field, obj) 354 | if out.Values[i] == graphql.Null { 355 | invalid = true 356 | } 357 | case "name": 358 | out.Values[i] = ec._Channel_name(ctx, field, obj) 359 | if out.Values[i] == graphql.Null { 360 | invalid = true 361 | } 362 | default: 363 | panic("unknown field " + strconv.Quote(field.Name)) 364 | } 365 | } 366 | 367 | if invalid { 368 | return graphql.Null 369 | } 370 | return out 371 | } 372 | 373 | // nolint: vetshadow 374 | func (ec *executionContext) _Channel_id(ctx context.Context, field graphql.CollectedField, obj *model.Channel) graphql.Marshaler { 375 | rctx := &graphql.ResolverContext{ 376 | Object: "Channel", 377 | Args: nil, 378 | Field: field, 379 | } 380 | ctx = graphql.WithResolverContext(ctx, rctx) 381 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 382 | return obj.ID, nil 383 | }) 384 | if resTmp == nil { 385 | if !ec.HasError(rctx) { 386 | ec.Errorf(ctx, "must not be null") 387 | } 388 | return graphql.Null 389 | } 390 | res := resTmp.(int) 391 | rctx.Result = res 392 | return graphql.MarshalInt(res) 393 | } 394 | 395 | // nolint: vetshadow 396 | func (ec *executionContext) _Channel_name(ctx context.Context, field graphql.CollectedField, obj *model.Channel) graphql.Marshaler { 397 | rctx := &graphql.ResolverContext{ 398 | Object: "Channel", 399 | Args: nil, 400 | Field: field, 401 | } 402 | ctx = graphql.WithResolverContext(ctx, rctx) 403 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 404 | return obj.Name, nil 405 | }) 406 | if resTmp == nil { 407 | if !ec.HasError(rctx) { 408 | ec.Errorf(ctx, "must not be null") 409 | } 410 | return graphql.Null 411 | } 412 | res := resTmp.(string) 413 | rctx.Result = res 414 | return graphql.MarshalString(res) 415 | } 416 | 417 | var mutationImplementors = []string{"Mutation"} 418 | 419 | // nolint: gocyclo, errcheck, gas, goconst 420 | func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { 421 | fields := graphql.CollectFields(ctx, sel, mutationImplementors) 422 | 423 | ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{ 424 | Object: "Mutation", 425 | }) 426 | 427 | out := graphql.NewOrderedMap(len(fields)) 428 | invalid := false 429 | for i, field := range fields { 430 | out.Keys[i] = field.Alias 431 | 432 | switch field.Name { 433 | case "__typename": 434 | out.Values[i] = graphql.MarshalString("Mutation") 435 | case "addChannel": 436 | out.Values[i] = ec._Mutation_addChannel(ctx, field) 437 | if out.Values[i] == graphql.Null { 438 | invalid = true 439 | } 440 | case "updateChannel": 441 | out.Values[i] = ec._Mutation_updateChannel(ctx, field) 442 | if out.Values[i] == graphql.Null { 443 | invalid = true 444 | } 445 | case "deleteChannel": 446 | out.Values[i] = ec._Mutation_deleteChannel(ctx, field) 447 | if out.Values[i] == graphql.Null { 448 | invalid = true 449 | } 450 | default: 451 | panic("unknown field " + strconv.Quote(field.Name)) 452 | } 453 | } 454 | 455 | if invalid { 456 | return graphql.Null 457 | } 458 | return out 459 | } 460 | 461 | // nolint: vetshadow 462 | func (ec *executionContext) _Mutation_addChannel(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { 463 | rawArgs := field.ArgumentMap(ec.Variables) 464 | args, err := field_Mutation_addChannel_args(rawArgs) 465 | if err != nil { 466 | ec.Error(ctx, err) 467 | return graphql.Null 468 | } 469 | rctx := &graphql.ResolverContext{ 470 | Object: "Mutation", 471 | Args: args, 472 | Field: field, 473 | } 474 | ctx = graphql.WithResolverContext(ctx, rctx) 475 | resTmp := ec.FieldMiddleware(ctx, nil, func(ctx context.Context) (interface{}, error) { 476 | return ec.resolvers.Mutation().AddChannel(ctx, args["name"].(string)) 477 | }) 478 | if resTmp == nil { 479 | if !ec.HasError(rctx) { 480 | ec.Errorf(ctx, "must not be null") 481 | } 482 | return graphql.Null 483 | } 484 | res := resTmp.(model.Channel) 485 | rctx.Result = res 486 | 487 | return ec._Channel(ctx, field.Selections, &res) 488 | } 489 | 490 | // nolint: vetshadow 491 | func (ec *executionContext) _Mutation_updateChannel(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { 492 | rawArgs := field.ArgumentMap(ec.Variables) 493 | args, err := field_Mutation_updateChannel_args(rawArgs) 494 | if err != nil { 495 | ec.Error(ctx, err) 496 | return graphql.Null 497 | } 498 | rctx := &graphql.ResolverContext{ 499 | Object: "Mutation", 500 | Args: args, 501 | Field: field, 502 | } 503 | ctx = graphql.WithResolverContext(ctx, rctx) 504 | resTmp := ec.FieldMiddleware(ctx, nil, func(ctx context.Context) (interface{}, error) { 505 | return ec.resolvers.Mutation().UpdateChannel(ctx, args["id"].(int), args["name"].(string)) 506 | }) 507 | if resTmp == nil { 508 | if !ec.HasError(rctx) { 509 | ec.Errorf(ctx, "must not be null") 510 | } 511 | return graphql.Null 512 | } 513 | res := resTmp.(model.Channel) 514 | rctx.Result = res 515 | 516 | return ec._Channel(ctx, field.Selections, &res) 517 | } 518 | 519 | // nolint: vetshadow 520 | func (ec *executionContext) _Mutation_deleteChannel(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { 521 | rawArgs := field.ArgumentMap(ec.Variables) 522 | args, err := field_Mutation_deleteChannel_args(rawArgs) 523 | if err != nil { 524 | ec.Error(ctx, err) 525 | return graphql.Null 526 | } 527 | rctx := &graphql.ResolverContext{ 528 | Object: "Mutation", 529 | Args: args, 530 | Field: field, 531 | } 532 | ctx = graphql.WithResolverContext(ctx, rctx) 533 | resTmp := ec.FieldMiddleware(ctx, nil, func(ctx context.Context) (interface{}, error) { 534 | return ec.resolvers.Mutation().DeleteChannel(ctx, args["ID"].(int)) 535 | }) 536 | if resTmp == nil { 537 | if !ec.HasError(rctx) { 538 | ec.Errorf(ctx, "must not be null") 539 | } 540 | return graphql.Null 541 | } 542 | res := resTmp.(model.Channel) 543 | rctx.Result = res 544 | 545 | return ec._Channel(ctx, field.Selections, &res) 546 | } 547 | 548 | var queryImplementors = []string{"Query"} 549 | 550 | // nolint: gocyclo, errcheck, gas, goconst 551 | func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { 552 | fields := graphql.CollectFields(ctx, sel, queryImplementors) 553 | 554 | ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{ 555 | Object: "Query", 556 | }) 557 | 558 | var wg sync.WaitGroup 559 | out := graphql.NewOrderedMap(len(fields)) 560 | invalid := false 561 | for i, field := range fields { 562 | out.Keys[i] = field.Alias 563 | 564 | switch field.Name { 565 | case "__typename": 566 | out.Values[i] = graphql.MarshalString("Query") 567 | case "channels": 568 | wg.Add(1) 569 | go func(i int, field graphql.CollectedField) { 570 | out.Values[i] = ec._Query_channels(ctx, field) 571 | if out.Values[i] == graphql.Null { 572 | invalid = true 573 | } 574 | wg.Done() 575 | }(i, field) 576 | case "__type": 577 | out.Values[i] = ec._Query___type(ctx, field) 578 | case "__schema": 579 | out.Values[i] = ec._Query___schema(ctx, field) 580 | default: 581 | panic("unknown field " + strconv.Quote(field.Name)) 582 | } 583 | } 584 | wg.Wait() 585 | if invalid { 586 | return graphql.Null 587 | } 588 | return out 589 | } 590 | 591 | // nolint: vetshadow 592 | func (ec *executionContext) _Query_channels(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { 593 | rctx := &graphql.ResolverContext{ 594 | Object: "Query", 595 | Args: nil, 596 | Field: field, 597 | } 598 | ctx = graphql.WithResolverContext(ctx, rctx) 599 | resTmp := ec.FieldMiddleware(ctx, nil, func(ctx context.Context) (interface{}, error) { 600 | return ec.resolvers.Query().Channels(ctx) 601 | }) 602 | if resTmp == nil { 603 | if !ec.HasError(rctx) { 604 | ec.Errorf(ctx, "must not be null") 605 | } 606 | return graphql.Null 607 | } 608 | res := resTmp.([]model.Channel) 609 | rctx.Result = res 610 | 611 | arr1 := make(graphql.Array, len(res)) 612 | var wg sync.WaitGroup 613 | 614 | isLen1 := len(res) == 1 615 | if !isLen1 { 616 | wg.Add(len(res)) 617 | } 618 | 619 | for idx1 := range res { 620 | idx1 := idx1 621 | rctx := &graphql.ResolverContext{ 622 | Index: &idx1, 623 | Result: &res[idx1], 624 | } 625 | ctx := graphql.WithResolverContext(ctx, rctx) 626 | f := func(idx1 int) { 627 | if !isLen1 { 628 | defer wg.Done() 629 | } 630 | arr1[idx1] = func() graphql.Marshaler { 631 | 632 | return ec._Channel(ctx, field.Selections, &res[idx1]) 633 | }() 634 | } 635 | if isLen1 { 636 | f(idx1) 637 | } else { 638 | go f(idx1) 639 | } 640 | 641 | } 642 | wg.Wait() 643 | return arr1 644 | } 645 | 646 | // nolint: vetshadow 647 | func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { 648 | rawArgs := field.ArgumentMap(ec.Variables) 649 | args, err := field_Query___type_args(rawArgs) 650 | if err != nil { 651 | ec.Error(ctx, err) 652 | return graphql.Null 653 | } 654 | rctx := &graphql.ResolverContext{ 655 | Object: "Query", 656 | Args: args, 657 | Field: field, 658 | } 659 | ctx = graphql.WithResolverContext(ctx, rctx) 660 | resTmp := ec.FieldMiddleware(ctx, nil, func(ctx context.Context) (interface{}, error) { 661 | return ec.introspectType(args["name"].(string)), nil 662 | }) 663 | if resTmp == nil { 664 | return graphql.Null 665 | } 666 | res := resTmp.(*introspection.Type) 667 | rctx.Result = res 668 | 669 | if res == nil { 670 | return graphql.Null 671 | } 672 | 673 | return ec.___Type(ctx, field.Selections, res) 674 | } 675 | 676 | // nolint: vetshadow 677 | func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { 678 | rctx := &graphql.ResolverContext{ 679 | Object: "Query", 680 | Args: nil, 681 | Field: field, 682 | } 683 | ctx = graphql.WithResolverContext(ctx, rctx) 684 | resTmp := ec.FieldMiddleware(ctx, nil, func(ctx context.Context) (interface{}, error) { 685 | return ec.introspectSchema(), nil 686 | }) 687 | if resTmp == nil { 688 | return graphql.Null 689 | } 690 | res := resTmp.(*introspection.Schema) 691 | rctx.Result = res 692 | 693 | if res == nil { 694 | return graphql.Null 695 | } 696 | 697 | return ec.___Schema(ctx, field.Selections, res) 698 | } 699 | 700 | var subscriptionImplementors = []string{"Subscription"} 701 | 702 | // nolint: gocyclo, errcheck, gas, goconst 703 | func (ec *executionContext) _Subscription(ctx context.Context, sel ast.SelectionSet) func() graphql.Marshaler { 704 | fields := graphql.CollectFields(ctx, sel, subscriptionImplementors) 705 | ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{ 706 | Object: "Subscription", 707 | }) 708 | if len(fields) != 1 { 709 | ec.Errorf(ctx, "must subscribe to exactly one stream") 710 | return nil 711 | } 712 | 713 | switch fields[0].Name { 714 | case "subscriptionChannelAdded": 715 | return ec._Subscription_subscriptionChannelAdded(ctx, fields[0]) 716 | case "subscriptionChannelDeleted": 717 | return ec._Subscription_subscriptionChannelDeleted(ctx, fields[0]) 718 | case "subscriptionChannelUpdated": 719 | return ec._Subscription_subscriptionChannelUpdated(ctx, fields[0]) 720 | default: 721 | panic("unknown field " + strconv.Quote(fields[0].Name)) 722 | } 723 | } 724 | 725 | func (ec *executionContext) _Subscription_subscriptionChannelAdded(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler { 726 | ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{ 727 | Field: field, 728 | }) 729 | results, err := ec.resolvers.Subscription().SubscriptionChannelAdded(ctx) 730 | if err != nil { 731 | ec.Error(ctx, err) 732 | return nil 733 | } 734 | return func() graphql.Marshaler { 735 | res, ok := <-results 736 | if !ok { 737 | return nil 738 | } 739 | var out graphql.OrderedMap 740 | out.Add(field.Alias, func() graphql.Marshaler { 741 | return ec._Channel(ctx, field.Selections, &res) 742 | }()) 743 | return &out 744 | } 745 | } 746 | 747 | func (ec *executionContext) _Subscription_subscriptionChannelDeleted(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler { 748 | ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{ 749 | Field: field, 750 | }) 751 | results, err := ec.resolvers.Subscription().SubscriptionChannelDeleted(ctx) 752 | if err != nil { 753 | ec.Error(ctx, err) 754 | return nil 755 | } 756 | return func() graphql.Marshaler { 757 | res, ok := <-results 758 | if !ok { 759 | return nil 760 | } 761 | var out graphql.OrderedMap 762 | out.Add(field.Alias, func() graphql.Marshaler { 763 | return ec._Channel(ctx, field.Selections, &res) 764 | }()) 765 | return &out 766 | } 767 | } 768 | 769 | func (ec *executionContext) _Subscription_subscriptionChannelUpdated(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler { 770 | ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{ 771 | Field: field, 772 | }) 773 | results, err := ec.resolvers.Subscription().SubscriptionChannelUpdated(ctx) 774 | if err != nil { 775 | ec.Error(ctx, err) 776 | return nil 777 | } 778 | return func() graphql.Marshaler { 779 | res, ok := <-results 780 | if !ok { 781 | return nil 782 | } 783 | var out graphql.OrderedMap 784 | out.Add(field.Alias, func() graphql.Marshaler { 785 | return ec._Channel(ctx, field.Selections, &res) 786 | }()) 787 | return &out 788 | } 789 | } 790 | 791 | var __DirectiveImplementors = []string{"__Directive"} 792 | 793 | // nolint: gocyclo, errcheck, gas, goconst 794 | func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { 795 | fields := graphql.CollectFields(ctx, sel, __DirectiveImplementors) 796 | 797 | out := graphql.NewOrderedMap(len(fields)) 798 | invalid := false 799 | for i, field := range fields { 800 | out.Keys[i] = field.Alias 801 | 802 | switch field.Name { 803 | case "__typename": 804 | out.Values[i] = graphql.MarshalString("__Directive") 805 | case "name": 806 | out.Values[i] = ec.___Directive_name(ctx, field, obj) 807 | if out.Values[i] == graphql.Null { 808 | invalid = true 809 | } 810 | case "description": 811 | out.Values[i] = ec.___Directive_description(ctx, field, obj) 812 | case "locations": 813 | out.Values[i] = ec.___Directive_locations(ctx, field, obj) 814 | if out.Values[i] == graphql.Null { 815 | invalid = true 816 | } 817 | case "args": 818 | out.Values[i] = ec.___Directive_args(ctx, field, obj) 819 | if out.Values[i] == graphql.Null { 820 | invalid = true 821 | } 822 | default: 823 | panic("unknown field " + strconv.Quote(field.Name)) 824 | } 825 | } 826 | 827 | if invalid { 828 | return graphql.Null 829 | } 830 | return out 831 | } 832 | 833 | // nolint: vetshadow 834 | func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) graphql.Marshaler { 835 | rctx := &graphql.ResolverContext{ 836 | Object: "__Directive", 837 | Args: nil, 838 | Field: field, 839 | } 840 | ctx = graphql.WithResolverContext(ctx, rctx) 841 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 842 | return obj.Name, nil 843 | }) 844 | if resTmp == nil { 845 | if !ec.HasError(rctx) { 846 | ec.Errorf(ctx, "must not be null") 847 | } 848 | return graphql.Null 849 | } 850 | res := resTmp.(string) 851 | rctx.Result = res 852 | return graphql.MarshalString(res) 853 | } 854 | 855 | // nolint: vetshadow 856 | func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) graphql.Marshaler { 857 | rctx := &graphql.ResolverContext{ 858 | Object: "__Directive", 859 | Args: nil, 860 | Field: field, 861 | } 862 | ctx = graphql.WithResolverContext(ctx, rctx) 863 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 864 | return obj.Description, nil 865 | }) 866 | if resTmp == nil { 867 | return graphql.Null 868 | } 869 | res := resTmp.(string) 870 | rctx.Result = res 871 | return graphql.MarshalString(res) 872 | } 873 | 874 | // nolint: vetshadow 875 | func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) graphql.Marshaler { 876 | rctx := &graphql.ResolverContext{ 877 | Object: "__Directive", 878 | Args: nil, 879 | Field: field, 880 | } 881 | ctx = graphql.WithResolverContext(ctx, rctx) 882 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 883 | return obj.Locations, nil 884 | }) 885 | if resTmp == nil { 886 | if !ec.HasError(rctx) { 887 | ec.Errorf(ctx, "must not be null") 888 | } 889 | return graphql.Null 890 | } 891 | res := resTmp.([]string) 892 | rctx.Result = res 893 | 894 | arr1 := make(graphql.Array, len(res)) 895 | 896 | for idx1 := range res { 897 | arr1[idx1] = func() graphql.Marshaler { 898 | return graphql.MarshalString(res[idx1]) 899 | }() 900 | } 901 | 902 | return arr1 903 | } 904 | 905 | // nolint: vetshadow 906 | func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) graphql.Marshaler { 907 | rctx := &graphql.ResolverContext{ 908 | Object: "__Directive", 909 | Args: nil, 910 | Field: field, 911 | } 912 | ctx = graphql.WithResolverContext(ctx, rctx) 913 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 914 | return obj.Args, nil 915 | }) 916 | if resTmp == nil { 917 | if !ec.HasError(rctx) { 918 | ec.Errorf(ctx, "must not be null") 919 | } 920 | return graphql.Null 921 | } 922 | res := resTmp.([]introspection.InputValue) 923 | rctx.Result = res 924 | 925 | arr1 := make(graphql.Array, len(res)) 926 | var wg sync.WaitGroup 927 | 928 | isLen1 := len(res) == 1 929 | if !isLen1 { 930 | wg.Add(len(res)) 931 | } 932 | 933 | for idx1 := range res { 934 | idx1 := idx1 935 | rctx := &graphql.ResolverContext{ 936 | Index: &idx1, 937 | Result: &res[idx1], 938 | } 939 | ctx := graphql.WithResolverContext(ctx, rctx) 940 | f := func(idx1 int) { 941 | if !isLen1 { 942 | defer wg.Done() 943 | } 944 | arr1[idx1] = func() graphql.Marshaler { 945 | 946 | return ec.___InputValue(ctx, field.Selections, &res[idx1]) 947 | }() 948 | } 949 | if isLen1 { 950 | f(idx1) 951 | } else { 952 | go f(idx1) 953 | } 954 | 955 | } 956 | wg.Wait() 957 | return arr1 958 | } 959 | 960 | var __EnumValueImplementors = []string{"__EnumValue"} 961 | 962 | // nolint: gocyclo, errcheck, gas, goconst 963 | func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { 964 | fields := graphql.CollectFields(ctx, sel, __EnumValueImplementors) 965 | 966 | out := graphql.NewOrderedMap(len(fields)) 967 | invalid := false 968 | for i, field := range fields { 969 | out.Keys[i] = field.Alias 970 | 971 | switch field.Name { 972 | case "__typename": 973 | out.Values[i] = graphql.MarshalString("__EnumValue") 974 | case "name": 975 | out.Values[i] = ec.___EnumValue_name(ctx, field, obj) 976 | if out.Values[i] == graphql.Null { 977 | invalid = true 978 | } 979 | case "description": 980 | out.Values[i] = ec.___EnumValue_description(ctx, field, obj) 981 | case "isDeprecated": 982 | out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) 983 | if out.Values[i] == graphql.Null { 984 | invalid = true 985 | } 986 | case "deprecationReason": 987 | out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) 988 | default: 989 | panic("unknown field " + strconv.Quote(field.Name)) 990 | } 991 | } 992 | 993 | if invalid { 994 | return graphql.Null 995 | } 996 | return out 997 | } 998 | 999 | // nolint: vetshadow 1000 | func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) graphql.Marshaler { 1001 | rctx := &graphql.ResolverContext{ 1002 | Object: "__EnumValue", 1003 | Args: nil, 1004 | Field: field, 1005 | } 1006 | ctx = graphql.WithResolverContext(ctx, rctx) 1007 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1008 | return obj.Name, nil 1009 | }) 1010 | if resTmp == nil { 1011 | if !ec.HasError(rctx) { 1012 | ec.Errorf(ctx, "must not be null") 1013 | } 1014 | return graphql.Null 1015 | } 1016 | res := resTmp.(string) 1017 | rctx.Result = res 1018 | return graphql.MarshalString(res) 1019 | } 1020 | 1021 | // nolint: vetshadow 1022 | func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) graphql.Marshaler { 1023 | rctx := &graphql.ResolverContext{ 1024 | Object: "__EnumValue", 1025 | Args: nil, 1026 | Field: field, 1027 | } 1028 | ctx = graphql.WithResolverContext(ctx, rctx) 1029 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1030 | return obj.Description, nil 1031 | }) 1032 | if resTmp == nil { 1033 | return graphql.Null 1034 | } 1035 | res := resTmp.(string) 1036 | rctx.Result = res 1037 | return graphql.MarshalString(res) 1038 | } 1039 | 1040 | // nolint: vetshadow 1041 | func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) graphql.Marshaler { 1042 | rctx := &graphql.ResolverContext{ 1043 | Object: "__EnumValue", 1044 | Args: nil, 1045 | Field: field, 1046 | } 1047 | ctx = graphql.WithResolverContext(ctx, rctx) 1048 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1049 | return obj.IsDeprecated, nil 1050 | }) 1051 | if resTmp == nil { 1052 | if !ec.HasError(rctx) { 1053 | ec.Errorf(ctx, "must not be null") 1054 | } 1055 | return graphql.Null 1056 | } 1057 | res := resTmp.(bool) 1058 | rctx.Result = res 1059 | return graphql.MarshalBoolean(res) 1060 | } 1061 | 1062 | // nolint: vetshadow 1063 | func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) graphql.Marshaler { 1064 | rctx := &graphql.ResolverContext{ 1065 | Object: "__EnumValue", 1066 | Args: nil, 1067 | Field: field, 1068 | } 1069 | ctx = graphql.WithResolverContext(ctx, rctx) 1070 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1071 | return obj.DeprecationReason, nil 1072 | }) 1073 | if resTmp == nil { 1074 | return graphql.Null 1075 | } 1076 | res := resTmp.(string) 1077 | rctx.Result = res 1078 | return graphql.MarshalString(res) 1079 | } 1080 | 1081 | var __FieldImplementors = []string{"__Field"} 1082 | 1083 | // nolint: gocyclo, errcheck, gas, goconst 1084 | func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { 1085 | fields := graphql.CollectFields(ctx, sel, __FieldImplementors) 1086 | 1087 | out := graphql.NewOrderedMap(len(fields)) 1088 | invalid := false 1089 | for i, field := range fields { 1090 | out.Keys[i] = field.Alias 1091 | 1092 | switch field.Name { 1093 | case "__typename": 1094 | out.Values[i] = graphql.MarshalString("__Field") 1095 | case "name": 1096 | out.Values[i] = ec.___Field_name(ctx, field, obj) 1097 | if out.Values[i] == graphql.Null { 1098 | invalid = true 1099 | } 1100 | case "description": 1101 | out.Values[i] = ec.___Field_description(ctx, field, obj) 1102 | case "args": 1103 | out.Values[i] = ec.___Field_args(ctx, field, obj) 1104 | if out.Values[i] == graphql.Null { 1105 | invalid = true 1106 | } 1107 | case "type": 1108 | out.Values[i] = ec.___Field_type(ctx, field, obj) 1109 | if out.Values[i] == graphql.Null { 1110 | invalid = true 1111 | } 1112 | case "isDeprecated": 1113 | out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) 1114 | if out.Values[i] == graphql.Null { 1115 | invalid = true 1116 | } 1117 | case "deprecationReason": 1118 | out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) 1119 | default: 1120 | panic("unknown field " + strconv.Quote(field.Name)) 1121 | } 1122 | } 1123 | 1124 | if invalid { 1125 | return graphql.Null 1126 | } 1127 | return out 1128 | } 1129 | 1130 | // nolint: vetshadow 1131 | func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { 1132 | rctx := &graphql.ResolverContext{ 1133 | Object: "__Field", 1134 | Args: nil, 1135 | Field: field, 1136 | } 1137 | ctx = graphql.WithResolverContext(ctx, rctx) 1138 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1139 | return obj.Name, nil 1140 | }) 1141 | if resTmp == nil { 1142 | if !ec.HasError(rctx) { 1143 | ec.Errorf(ctx, "must not be null") 1144 | } 1145 | return graphql.Null 1146 | } 1147 | res := resTmp.(string) 1148 | rctx.Result = res 1149 | return graphql.MarshalString(res) 1150 | } 1151 | 1152 | // nolint: vetshadow 1153 | func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { 1154 | rctx := &graphql.ResolverContext{ 1155 | Object: "__Field", 1156 | Args: nil, 1157 | Field: field, 1158 | } 1159 | ctx = graphql.WithResolverContext(ctx, rctx) 1160 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1161 | return obj.Description, nil 1162 | }) 1163 | if resTmp == nil { 1164 | return graphql.Null 1165 | } 1166 | res := resTmp.(string) 1167 | rctx.Result = res 1168 | return graphql.MarshalString(res) 1169 | } 1170 | 1171 | // nolint: vetshadow 1172 | func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { 1173 | rctx := &graphql.ResolverContext{ 1174 | Object: "__Field", 1175 | Args: nil, 1176 | Field: field, 1177 | } 1178 | ctx = graphql.WithResolverContext(ctx, rctx) 1179 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1180 | return obj.Args, nil 1181 | }) 1182 | if resTmp == nil { 1183 | if !ec.HasError(rctx) { 1184 | ec.Errorf(ctx, "must not be null") 1185 | } 1186 | return graphql.Null 1187 | } 1188 | res := resTmp.([]introspection.InputValue) 1189 | rctx.Result = res 1190 | 1191 | arr1 := make(graphql.Array, len(res)) 1192 | var wg sync.WaitGroup 1193 | 1194 | isLen1 := len(res) == 1 1195 | if !isLen1 { 1196 | wg.Add(len(res)) 1197 | } 1198 | 1199 | for idx1 := range res { 1200 | idx1 := idx1 1201 | rctx := &graphql.ResolverContext{ 1202 | Index: &idx1, 1203 | Result: &res[idx1], 1204 | } 1205 | ctx := graphql.WithResolverContext(ctx, rctx) 1206 | f := func(idx1 int) { 1207 | if !isLen1 { 1208 | defer wg.Done() 1209 | } 1210 | arr1[idx1] = func() graphql.Marshaler { 1211 | 1212 | return ec.___InputValue(ctx, field.Selections, &res[idx1]) 1213 | }() 1214 | } 1215 | if isLen1 { 1216 | f(idx1) 1217 | } else { 1218 | go f(idx1) 1219 | } 1220 | 1221 | } 1222 | wg.Wait() 1223 | return arr1 1224 | } 1225 | 1226 | // nolint: vetshadow 1227 | func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { 1228 | rctx := &graphql.ResolverContext{ 1229 | Object: "__Field", 1230 | Args: nil, 1231 | Field: field, 1232 | } 1233 | ctx = graphql.WithResolverContext(ctx, rctx) 1234 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1235 | return obj.Type, nil 1236 | }) 1237 | if resTmp == nil { 1238 | if !ec.HasError(rctx) { 1239 | ec.Errorf(ctx, "must not be null") 1240 | } 1241 | return graphql.Null 1242 | } 1243 | res := resTmp.(*introspection.Type) 1244 | rctx.Result = res 1245 | 1246 | if res == nil { 1247 | if !ec.HasError(rctx) { 1248 | ec.Errorf(ctx, "must not be null") 1249 | } 1250 | return graphql.Null 1251 | } 1252 | 1253 | return ec.___Type(ctx, field.Selections, res) 1254 | } 1255 | 1256 | // nolint: vetshadow 1257 | func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { 1258 | rctx := &graphql.ResolverContext{ 1259 | Object: "__Field", 1260 | Args: nil, 1261 | Field: field, 1262 | } 1263 | ctx = graphql.WithResolverContext(ctx, rctx) 1264 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1265 | return obj.IsDeprecated, nil 1266 | }) 1267 | if resTmp == nil { 1268 | if !ec.HasError(rctx) { 1269 | ec.Errorf(ctx, "must not be null") 1270 | } 1271 | return graphql.Null 1272 | } 1273 | res := resTmp.(bool) 1274 | rctx.Result = res 1275 | return graphql.MarshalBoolean(res) 1276 | } 1277 | 1278 | // nolint: vetshadow 1279 | func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { 1280 | rctx := &graphql.ResolverContext{ 1281 | Object: "__Field", 1282 | Args: nil, 1283 | Field: field, 1284 | } 1285 | ctx = graphql.WithResolverContext(ctx, rctx) 1286 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1287 | return obj.DeprecationReason, nil 1288 | }) 1289 | if resTmp == nil { 1290 | return graphql.Null 1291 | } 1292 | res := resTmp.(string) 1293 | rctx.Result = res 1294 | return graphql.MarshalString(res) 1295 | } 1296 | 1297 | var __InputValueImplementors = []string{"__InputValue"} 1298 | 1299 | // nolint: gocyclo, errcheck, gas, goconst 1300 | func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { 1301 | fields := graphql.CollectFields(ctx, sel, __InputValueImplementors) 1302 | 1303 | out := graphql.NewOrderedMap(len(fields)) 1304 | invalid := false 1305 | for i, field := range fields { 1306 | out.Keys[i] = field.Alias 1307 | 1308 | switch field.Name { 1309 | case "__typename": 1310 | out.Values[i] = graphql.MarshalString("__InputValue") 1311 | case "name": 1312 | out.Values[i] = ec.___InputValue_name(ctx, field, obj) 1313 | if out.Values[i] == graphql.Null { 1314 | invalid = true 1315 | } 1316 | case "description": 1317 | out.Values[i] = ec.___InputValue_description(ctx, field, obj) 1318 | case "type": 1319 | out.Values[i] = ec.___InputValue_type(ctx, field, obj) 1320 | if out.Values[i] == graphql.Null { 1321 | invalid = true 1322 | } 1323 | case "defaultValue": 1324 | out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) 1325 | default: 1326 | panic("unknown field " + strconv.Quote(field.Name)) 1327 | } 1328 | } 1329 | 1330 | if invalid { 1331 | return graphql.Null 1332 | } 1333 | return out 1334 | } 1335 | 1336 | // nolint: vetshadow 1337 | func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { 1338 | rctx := &graphql.ResolverContext{ 1339 | Object: "__InputValue", 1340 | Args: nil, 1341 | Field: field, 1342 | } 1343 | ctx = graphql.WithResolverContext(ctx, rctx) 1344 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1345 | return obj.Name, nil 1346 | }) 1347 | if resTmp == nil { 1348 | if !ec.HasError(rctx) { 1349 | ec.Errorf(ctx, "must not be null") 1350 | } 1351 | return graphql.Null 1352 | } 1353 | res := resTmp.(string) 1354 | rctx.Result = res 1355 | return graphql.MarshalString(res) 1356 | } 1357 | 1358 | // nolint: vetshadow 1359 | func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { 1360 | rctx := &graphql.ResolverContext{ 1361 | Object: "__InputValue", 1362 | Args: nil, 1363 | Field: field, 1364 | } 1365 | ctx = graphql.WithResolverContext(ctx, rctx) 1366 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1367 | return obj.Description, nil 1368 | }) 1369 | if resTmp == nil { 1370 | return graphql.Null 1371 | } 1372 | res := resTmp.(string) 1373 | rctx.Result = res 1374 | return graphql.MarshalString(res) 1375 | } 1376 | 1377 | // nolint: vetshadow 1378 | func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { 1379 | rctx := &graphql.ResolverContext{ 1380 | Object: "__InputValue", 1381 | Args: nil, 1382 | Field: field, 1383 | } 1384 | ctx = graphql.WithResolverContext(ctx, rctx) 1385 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1386 | return obj.Type, nil 1387 | }) 1388 | if resTmp == nil { 1389 | if !ec.HasError(rctx) { 1390 | ec.Errorf(ctx, "must not be null") 1391 | } 1392 | return graphql.Null 1393 | } 1394 | res := resTmp.(*introspection.Type) 1395 | rctx.Result = res 1396 | 1397 | if res == nil { 1398 | if !ec.HasError(rctx) { 1399 | ec.Errorf(ctx, "must not be null") 1400 | } 1401 | return graphql.Null 1402 | } 1403 | 1404 | return ec.___Type(ctx, field.Selections, res) 1405 | } 1406 | 1407 | // nolint: vetshadow 1408 | func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { 1409 | rctx := &graphql.ResolverContext{ 1410 | Object: "__InputValue", 1411 | Args: nil, 1412 | Field: field, 1413 | } 1414 | ctx = graphql.WithResolverContext(ctx, rctx) 1415 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1416 | return obj.DefaultValue, nil 1417 | }) 1418 | if resTmp == nil { 1419 | return graphql.Null 1420 | } 1421 | res := resTmp.(*string) 1422 | rctx.Result = res 1423 | 1424 | if res == nil { 1425 | return graphql.Null 1426 | } 1427 | return graphql.MarshalString(*res) 1428 | } 1429 | 1430 | var __SchemaImplementors = []string{"__Schema"} 1431 | 1432 | // nolint: gocyclo, errcheck, gas, goconst 1433 | func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { 1434 | fields := graphql.CollectFields(ctx, sel, __SchemaImplementors) 1435 | 1436 | out := graphql.NewOrderedMap(len(fields)) 1437 | invalid := false 1438 | for i, field := range fields { 1439 | out.Keys[i] = field.Alias 1440 | 1441 | switch field.Name { 1442 | case "__typename": 1443 | out.Values[i] = graphql.MarshalString("__Schema") 1444 | case "types": 1445 | out.Values[i] = ec.___Schema_types(ctx, field, obj) 1446 | if out.Values[i] == graphql.Null { 1447 | invalid = true 1448 | } 1449 | case "queryType": 1450 | out.Values[i] = ec.___Schema_queryType(ctx, field, obj) 1451 | if out.Values[i] == graphql.Null { 1452 | invalid = true 1453 | } 1454 | case "mutationType": 1455 | out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) 1456 | case "subscriptionType": 1457 | out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) 1458 | case "directives": 1459 | out.Values[i] = ec.___Schema_directives(ctx, field, obj) 1460 | if out.Values[i] == graphql.Null { 1461 | invalid = true 1462 | } 1463 | default: 1464 | panic("unknown field " + strconv.Quote(field.Name)) 1465 | } 1466 | } 1467 | 1468 | if invalid { 1469 | return graphql.Null 1470 | } 1471 | return out 1472 | } 1473 | 1474 | // nolint: vetshadow 1475 | func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { 1476 | rctx := &graphql.ResolverContext{ 1477 | Object: "__Schema", 1478 | Args: nil, 1479 | Field: field, 1480 | } 1481 | ctx = graphql.WithResolverContext(ctx, rctx) 1482 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1483 | return obj.Types(), nil 1484 | }) 1485 | if resTmp == nil { 1486 | if !ec.HasError(rctx) { 1487 | ec.Errorf(ctx, "must not be null") 1488 | } 1489 | return graphql.Null 1490 | } 1491 | res := resTmp.([]introspection.Type) 1492 | rctx.Result = res 1493 | 1494 | arr1 := make(graphql.Array, len(res)) 1495 | var wg sync.WaitGroup 1496 | 1497 | isLen1 := len(res) == 1 1498 | if !isLen1 { 1499 | wg.Add(len(res)) 1500 | } 1501 | 1502 | for idx1 := range res { 1503 | idx1 := idx1 1504 | rctx := &graphql.ResolverContext{ 1505 | Index: &idx1, 1506 | Result: &res[idx1], 1507 | } 1508 | ctx := graphql.WithResolverContext(ctx, rctx) 1509 | f := func(idx1 int) { 1510 | if !isLen1 { 1511 | defer wg.Done() 1512 | } 1513 | arr1[idx1] = func() graphql.Marshaler { 1514 | 1515 | return ec.___Type(ctx, field.Selections, &res[idx1]) 1516 | }() 1517 | } 1518 | if isLen1 { 1519 | f(idx1) 1520 | } else { 1521 | go f(idx1) 1522 | } 1523 | 1524 | } 1525 | wg.Wait() 1526 | return arr1 1527 | } 1528 | 1529 | // nolint: vetshadow 1530 | func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { 1531 | rctx := &graphql.ResolverContext{ 1532 | Object: "__Schema", 1533 | Args: nil, 1534 | Field: field, 1535 | } 1536 | ctx = graphql.WithResolverContext(ctx, rctx) 1537 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1538 | return obj.QueryType(), nil 1539 | }) 1540 | if resTmp == nil { 1541 | if !ec.HasError(rctx) { 1542 | ec.Errorf(ctx, "must not be null") 1543 | } 1544 | return graphql.Null 1545 | } 1546 | res := resTmp.(*introspection.Type) 1547 | rctx.Result = res 1548 | 1549 | if res == nil { 1550 | if !ec.HasError(rctx) { 1551 | ec.Errorf(ctx, "must not be null") 1552 | } 1553 | return graphql.Null 1554 | } 1555 | 1556 | return ec.___Type(ctx, field.Selections, res) 1557 | } 1558 | 1559 | // nolint: vetshadow 1560 | func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { 1561 | rctx := &graphql.ResolverContext{ 1562 | Object: "__Schema", 1563 | Args: nil, 1564 | Field: field, 1565 | } 1566 | ctx = graphql.WithResolverContext(ctx, rctx) 1567 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1568 | return obj.MutationType(), nil 1569 | }) 1570 | if resTmp == nil { 1571 | return graphql.Null 1572 | } 1573 | res := resTmp.(*introspection.Type) 1574 | rctx.Result = res 1575 | 1576 | if res == nil { 1577 | return graphql.Null 1578 | } 1579 | 1580 | return ec.___Type(ctx, field.Selections, res) 1581 | } 1582 | 1583 | // nolint: vetshadow 1584 | func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { 1585 | rctx := &graphql.ResolverContext{ 1586 | Object: "__Schema", 1587 | Args: nil, 1588 | Field: field, 1589 | } 1590 | ctx = graphql.WithResolverContext(ctx, rctx) 1591 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1592 | return obj.SubscriptionType(), nil 1593 | }) 1594 | if resTmp == nil { 1595 | return graphql.Null 1596 | } 1597 | res := resTmp.(*introspection.Type) 1598 | rctx.Result = res 1599 | 1600 | if res == nil { 1601 | return graphql.Null 1602 | } 1603 | 1604 | return ec.___Type(ctx, field.Selections, res) 1605 | } 1606 | 1607 | // nolint: vetshadow 1608 | func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { 1609 | rctx := &graphql.ResolverContext{ 1610 | Object: "__Schema", 1611 | Args: nil, 1612 | Field: field, 1613 | } 1614 | ctx = graphql.WithResolverContext(ctx, rctx) 1615 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1616 | return obj.Directives(), nil 1617 | }) 1618 | if resTmp == nil { 1619 | if !ec.HasError(rctx) { 1620 | ec.Errorf(ctx, "must not be null") 1621 | } 1622 | return graphql.Null 1623 | } 1624 | res := resTmp.([]introspection.Directive) 1625 | rctx.Result = res 1626 | 1627 | arr1 := make(graphql.Array, len(res)) 1628 | var wg sync.WaitGroup 1629 | 1630 | isLen1 := len(res) == 1 1631 | if !isLen1 { 1632 | wg.Add(len(res)) 1633 | } 1634 | 1635 | for idx1 := range res { 1636 | idx1 := idx1 1637 | rctx := &graphql.ResolverContext{ 1638 | Index: &idx1, 1639 | Result: &res[idx1], 1640 | } 1641 | ctx := graphql.WithResolverContext(ctx, rctx) 1642 | f := func(idx1 int) { 1643 | if !isLen1 { 1644 | defer wg.Done() 1645 | } 1646 | arr1[idx1] = func() graphql.Marshaler { 1647 | 1648 | return ec.___Directive(ctx, field.Selections, &res[idx1]) 1649 | }() 1650 | } 1651 | if isLen1 { 1652 | f(idx1) 1653 | } else { 1654 | go f(idx1) 1655 | } 1656 | 1657 | } 1658 | wg.Wait() 1659 | return arr1 1660 | } 1661 | 1662 | var __TypeImplementors = []string{"__Type"} 1663 | 1664 | // nolint: gocyclo, errcheck, gas, goconst 1665 | func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { 1666 | fields := graphql.CollectFields(ctx, sel, __TypeImplementors) 1667 | 1668 | out := graphql.NewOrderedMap(len(fields)) 1669 | invalid := false 1670 | for i, field := range fields { 1671 | out.Keys[i] = field.Alias 1672 | 1673 | switch field.Name { 1674 | case "__typename": 1675 | out.Values[i] = graphql.MarshalString("__Type") 1676 | case "kind": 1677 | out.Values[i] = ec.___Type_kind(ctx, field, obj) 1678 | if out.Values[i] == graphql.Null { 1679 | invalid = true 1680 | } 1681 | case "name": 1682 | out.Values[i] = ec.___Type_name(ctx, field, obj) 1683 | case "description": 1684 | out.Values[i] = ec.___Type_description(ctx, field, obj) 1685 | case "fields": 1686 | out.Values[i] = ec.___Type_fields(ctx, field, obj) 1687 | case "interfaces": 1688 | out.Values[i] = ec.___Type_interfaces(ctx, field, obj) 1689 | case "possibleTypes": 1690 | out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) 1691 | case "enumValues": 1692 | out.Values[i] = ec.___Type_enumValues(ctx, field, obj) 1693 | case "inputFields": 1694 | out.Values[i] = ec.___Type_inputFields(ctx, field, obj) 1695 | case "ofType": 1696 | out.Values[i] = ec.___Type_ofType(ctx, field, obj) 1697 | default: 1698 | panic("unknown field " + strconv.Quote(field.Name)) 1699 | } 1700 | } 1701 | 1702 | if invalid { 1703 | return graphql.Null 1704 | } 1705 | return out 1706 | } 1707 | 1708 | // nolint: vetshadow 1709 | func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { 1710 | rctx := &graphql.ResolverContext{ 1711 | Object: "__Type", 1712 | Args: nil, 1713 | Field: field, 1714 | } 1715 | ctx = graphql.WithResolverContext(ctx, rctx) 1716 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1717 | return obj.Kind(), nil 1718 | }) 1719 | if resTmp == nil { 1720 | if !ec.HasError(rctx) { 1721 | ec.Errorf(ctx, "must not be null") 1722 | } 1723 | return graphql.Null 1724 | } 1725 | res := resTmp.(string) 1726 | rctx.Result = res 1727 | return graphql.MarshalString(res) 1728 | } 1729 | 1730 | // nolint: vetshadow 1731 | func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { 1732 | rctx := &graphql.ResolverContext{ 1733 | Object: "__Type", 1734 | Args: nil, 1735 | Field: field, 1736 | } 1737 | ctx = graphql.WithResolverContext(ctx, rctx) 1738 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1739 | return obj.Name(), nil 1740 | }) 1741 | if resTmp == nil { 1742 | return graphql.Null 1743 | } 1744 | res := resTmp.(*string) 1745 | rctx.Result = res 1746 | 1747 | if res == nil { 1748 | return graphql.Null 1749 | } 1750 | return graphql.MarshalString(*res) 1751 | } 1752 | 1753 | // nolint: vetshadow 1754 | func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { 1755 | rctx := &graphql.ResolverContext{ 1756 | Object: "__Type", 1757 | Args: nil, 1758 | Field: field, 1759 | } 1760 | ctx = graphql.WithResolverContext(ctx, rctx) 1761 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1762 | return obj.Description(), nil 1763 | }) 1764 | if resTmp == nil { 1765 | return graphql.Null 1766 | } 1767 | res := resTmp.(string) 1768 | rctx.Result = res 1769 | return graphql.MarshalString(res) 1770 | } 1771 | 1772 | // nolint: vetshadow 1773 | func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { 1774 | rawArgs := field.ArgumentMap(ec.Variables) 1775 | args, err := field___Type_fields_args(rawArgs) 1776 | if err != nil { 1777 | ec.Error(ctx, err) 1778 | return graphql.Null 1779 | } 1780 | rctx := &graphql.ResolverContext{ 1781 | Object: "__Type", 1782 | Args: args, 1783 | Field: field, 1784 | } 1785 | ctx = graphql.WithResolverContext(ctx, rctx) 1786 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1787 | return obj.Fields(args["includeDeprecated"].(bool)), nil 1788 | }) 1789 | if resTmp == nil { 1790 | return graphql.Null 1791 | } 1792 | res := resTmp.([]introspection.Field) 1793 | rctx.Result = res 1794 | 1795 | arr1 := make(graphql.Array, len(res)) 1796 | var wg sync.WaitGroup 1797 | 1798 | isLen1 := len(res) == 1 1799 | if !isLen1 { 1800 | wg.Add(len(res)) 1801 | } 1802 | 1803 | for idx1 := range res { 1804 | idx1 := idx1 1805 | rctx := &graphql.ResolverContext{ 1806 | Index: &idx1, 1807 | Result: &res[idx1], 1808 | } 1809 | ctx := graphql.WithResolverContext(ctx, rctx) 1810 | f := func(idx1 int) { 1811 | if !isLen1 { 1812 | defer wg.Done() 1813 | } 1814 | arr1[idx1] = func() graphql.Marshaler { 1815 | 1816 | return ec.___Field(ctx, field.Selections, &res[idx1]) 1817 | }() 1818 | } 1819 | if isLen1 { 1820 | f(idx1) 1821 | } else { 1822 | go f(idx1) 1823 | } 1824 | 1825 | } 1826 | wg.Wait() 1827 | return arr1 1828 | } 1829 | 1830 | // nolint: vetshadow 1831 | func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { 1832 | rctx := &graphql.ResolverContext{ 1833 | Object: "__Type", 1834 | Args: nil, 1835 | Field: field, 1836 | } 1837 | ctx = graphql.WithResolverContext(ctx, rctx) 1838 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1839 | return obj.Interfaces(), nil 1840 | }) 1841 | if resTmp == nil { 1842 | return graphql.Null 1843 | } 1844 | res := resTmp.([]introspection.Type) 1845 | rctx.Result = res 1846 | 1847 | arr1 := make(graphql.Array, len(res)) 1848 | var wg sync.WaitGroup 1849 | 1850 | isLen1 := len(res) == 1 1851 | if !isLen1 { 1852 | wg.Add(len(res)) 1853 | } 1854 | 1855 | for idx1 := range res { 1856 | idx1 := idx1 1857 | rctx := &graphql.ResolverContext{ 1858 | Index: &idx1, 1859 | Result: &res[idx1], 1860 | } 1861 | ctx := graphql.WithResolverContext(ctx, rctx) 1862 | f := func(idx1 int) { 1863 | if !isLen1 { 1864 | defer wg.Done() 1865 | } 1866 | arr1[idx1] = func() graphql.Marshaler { 1867 | 1868 | return ec.___Type(ctx, field.Selections, &res[idx1]) 1869 | }() 1870 | } 1871 | if isLen1 { 1872 | f(idx1) 1873 | } else { 1874 | go f(idx1) 1875 | } 1876 | 1877 | } 1878 | wg.Wait() 1879 | return arr1 1880 | } 1881 | 1882 | // nolint: vetshadow 1883 | func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { 1884 | rctx := &graphql.ResolverContext{ 1885 | Object: "__Type", 1886 | Args: nil, 1887 | Field: field, 1888 | } 1889 | ctx = graphql.WithResolverContext(ctx, rctx) 1890 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1891 | return obj.PossibleTypes(), nil 1892 | }) 1893 | if resTmp == nil { 1894 | return graphql.Null 1895 | } 1896 | res := resTmp.([]introspection.Type) 1897 | rctx.Result = res 1898 | 1899 | arr1 := make(graphql.Array, len(res)) 1900 | var wg sync.WaitGroup 1901 | 1902 | isLen1 := len(res) == 1 1903 | if !isLen1 { 1904 | wg.Add(len(res)) 1905 | } 1906 | 1907 | for idx1 := range res { 1908 | idx1 := idx1 1909 | rctx := &graphql.ResolverContext{ 1910 | Index: &idx1, 1911 | Result: &res[idx1], 1912 | } 1913 | ctx := graphql.WithResolverContext(ctx, rctx) 1914 | f := func(idx1 int) { 1915 | if !isLen1 { 1916 | defer wg.Done() 1917 | } 1918 | arr1[idx1] = func() graphql.Marshaler { 1919 | 1920 | return ec.___Type(ctx, field.Selections, &res[idx1]) 1921 | }() 1922 | } 1923 | if isLen1 { 1924 | f(idx1) 1925 | } else { 1926 | go f(idx1) 1927 | } 1928 | 1929 | } 1930 | wg.Wait() 1931 | return arr1 1932 | } 1933 | 1934 | // nolint: vetshadow 1935 | func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { 1936 | rawArgs := field.ArgumentMap(ec.Variables) 1937 | args, err := field___Type_enumValues_args(rawArgs) 1938 | if err != nil { 1939 | ec.Error(ctx, err) 1940 | return graphql.Null 1941 | } 1942 | rctx := &graphql.ResolverContext{ 1943 | Object: "__Type", 1944 | Args: args, 1945 | Field: field, 1946 | } 1947 | ctx = graphql.WithResolverContext(ctx, rctx) 1948 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 1949 | return obj.EnumValues(args["includeDeprecated"].(bool)), nil 1950 | }) 1951 | if resTmp == nil { 1952 | return graphql.Null 1953 | } 1954 | res := resTmp.([]introspection.EnumValue) 1955 | rctx.Result = res 1956 | 1957 | arr1 := make(graphql.Array, len(res)) 1958 | var wg sync.WaitGroup 1959 | 1960 | isLen1 := len(res) == 1 1961 | if !isLen1 { 1962 | wg.Add(len(res)) 1963 | } 1964 | 1965 | for idx1 := range res { 1966 | idx1 := idx1 1967 | rctx := &graphql.ResolverContext{ 1968 | Index: &idx1, 1969 | Result: &res[idx1], 1970 | } 1971 | ctx := graphql.WithResolverContext(ctx, rctx) 1972 | f := func(idx1 int) { 1973 | if !isLen1 { 1974 | defer wg.Done() 1975 | } 1976 | arr1[idx1] = func() graphql.Marshaler { 1977 | 1978 | return ec.___EnumValue(ctx, field.Selections, &res[idx1]) 1979 | }() 1980 | } 1981 | if isLen1 { 1982 | f(idx1) 1983 | } else { 1984 | go f(idx1) 1985 | } 1986 | 1987 | } 1988 | wg.Wait() 1989 | return arr1 1990 | } 1991 | 1992 | // nolint: vetshadow 1993 | func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { 1994 | rctx := &graphql.ResolverContext{ 1995 | Object: "__Type", 1996 | Args: nil, 1997 | Field: field, 1998 | } 1999 | ctx = graphql.WithResolverContext(ctx, rctx) 2000 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 2001 | return obj.InputFields(), nil 2002 | }) 2003 | if resTmp == nil { 2004 | return graphql.Null 2005 | } 2006 | res := resTmp.([]introspection.InputValue) 2007 | rctx.Result = res 2008 | 2009 | arr1 := make(graphql.Array, len(res)) 2010 | var wg sync.WaitGroup 2011 | 2012 | isLen1 := len(res) == 1 2013 | if !isLen1 { 2014 | wg.Add(len(res)) 2015 | } 2016 | 2017 | for idx1 := range res { 2018 | idx1 := idx1 2019 | rctx := &graphql.ResolverContext{ 2020 | Index: &idx1, 2021 | Result: &res[idx1], 2022 | } 2023 | ctx := graphql.WithResolverContext(ctx, rctx) 2024 | f := func(idx1 int) { 2025 | if !isLen1 { 2026 | defer wg.Done() 2027 | } 2028 | arr1[idx1] = func() graphql.Marshaler { 2029 | 2030 | return ec.___InputValue(ctx, field.Selections, &res[idx1]) 2031 | }() 2032 | } 2033 | if isLen1 { 2034 | f(idx1) 2035 | } else { 2036 | go f(idx1) 2037 | } 2038 | 2039 | } 2040 | wg.Wait() 2041 | return arr1 2042 | } 2043 | 2044 | // nolint: vetshadow 2045 | func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { 2046 | rctx := &graphql.ResolverContext{ 2047 | Object: "__Type", 2048 | Args: nil, 2049 | Field: field, 2050 | } 2051 | ctx = graphql.WithResolverContext(ctx, rctx) 2052 | resTmp := ec.FieldMiddleware(ctx, obj, func(ctx context.Context) (interface{}, error) { 2053 | return obj.OfType(), nil 2054 | }) 2055 | if resTmp == nil { 2056 | return graphql.Null 2057 | } 2058 | res := resTmp.(*introspection.Type) 2059 | rctx.Result = res 2060 | 2061 | if res == nil { 2062 | return graphql.Null 2063 | } 2064 | 2065 | return ec.___Type(ctx, field.Selections, res) 2066 | } 2067 | 2068 | func (ec *executionContext) FieldMiddleware(ctx context.Context, obj interface{}, next graphql.Resolver) (ret interface{}) { 2069 | defer func() { 2070 | if r := recover(); r != nil { 2071 | ec.Error(ctx, ec.Recover(ctx, r)) 2072 | ret = nil 2073 | } 2074 | }() 2075 | res, err := ec.ResolverMiddleware(ctx, next) 2076 | if err != nil { 2077 | ec.Error(ctx, err) 2078 | return nil 2079 | } 2080 | return res 2081 | } 2082 | 2083 | func (ec *executionContext) introspectSchema() *introspection.Schema { 2084 | return introspection.WrapSchema(parsedSchema) 2085 | } 2086 | 2087 | func (ec *executionContext) introspectType(name string) *introspection.Type { 2088 | return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]) 2089 | } 2090 | 2091 | var parsedSchema = gqlparser.MustLoadSchema( 2092 | &ast.Source{Name: "schema.graphql", Input: ` 2093 | type Channel { 2094 | id: Int! # "!" denotes a required field 2095 | name: String! 2096 | } 2097 | 2098 | type Query { 2099 | channels: [Channel!]! 2100 | } 2101 | 2102 | type Mutation { 2103 | addChannel(name: String!): Channel! 2104 | updateChannel(id:Int!,name: String!): Channel! 2105 | deleteChannel(ID: Int!): Channel! 2106 | } 2107 | 2108 | type Subscription { 2109 | subscriptionChannelAdded: Channel! 2110 | subscriptionChannelDeleted: Channel! 2111 | subscriptionChannelUpdated: Channel! 2112 | } 2113 | `}, 2114 | ) 2115 | -------------------------------------------------------------------------------- /golang/app/model/models_gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT. 2 | 3 | package model 4 | 5 | type Channel struct { 6 | ID int `json:"id"` 7 | Name string `json:"name"` 8 | } 9 | -------------------------------------------------------------------------------- /golang/app/resolver/ChannelResolver.go: -------------------------------------------------------------------------------- 1 | package resolver 2 | 3 | import ( 4 | context "context" 5 | "golang-gqlgen-reactjs-subscription-demo/golang/app/config/connection" 6 | "golang-gqlgen-reactjs-subscription-demo/golang/app/model" 7 | ) 8 | 9 | type channelResolver struct{ *Resolver } 10 | 11 | var addChannelObserver map[string]chan model.Channel 12 | var deleteChannelObserver map[string]chan model.Channel 13 | var updateChannelObserver map[string]chan model.Channel 14 | 15 | func init() { 16 | addChannelObserver = map[string]chan model.Channel{} 17 | deleteChannelObserver = map[string]chan model.Channel{} 18 | updateChannelObserver = map[string]chan model.Channel{} 19 | } 20 | func (r *queryResolver) Channels(ctx context.Context) ([]model.Channel, error) { 21 | db := connection.DbConn() 22 | var query = "SELECT * FROM channel" 23 | selDB, err := db.Query(query) 24 | var arrChannel []model.Channel 25 | for selDB.Next() { 26 | var name string 27 | var id int64 28 | err = selDB.Scan(&id, &name) 29 | if err != nil { 30 | panic(err.Error()) 31 | } 32 | todo1 := model.Channel{ID: int(id), Name: name} 33 | arrChannel = append(arrChannel, todo1) 34 | } 35 | 36 | defer db.Close() 37 | return arrChannel, nil 38 | } 39 | 40 | func (r *mutationResolver) AddChannel(ctx context.Context, name string) (model.Channel, error) { 41 | db := connection.DbConn() 42 | 43 | insForm, err := db.Prepare("INSERT INTO channel(name) VALUES(?)") 44 | if err != nil { 45 | panic(err.Error()) 46 | } 47 | 48 | var newChannel model.Channel 49 | res, err := insForm.Exec(name) 50 | if err != nil { 51 | println("Exec err:", err.Error()) 52 | } else { 53 | var id int64 54 | id, err := res.LastInsertId() 55 | if err != nil { 56 | println("Error:", err.Error()) 57 | } else { 58 | newChannel = model.Channel{ID: int(id), Name: name} 59 | } 60 | } 61 | defer db.Close() 62 | //add new chanel in observer 63 | for _, observer := range addChannelObserver { 64 | observer <- newChannel 65 | } 66 | return newChannel, nil 67 | } 68 | func (r *mutationResolver) DeleteChannel(ctx context.Context, ID int) (model.Channel, error) { 69 | db := connection.DbConn() 70 | 71 | delForm, err := db.Prepare("DELETE FROM channel WHERE id=?") 72 | if err != nil { 73 | panic(err.Error()) 74 | } 75 | delForm.Exec(ID) 76 | var newChannel model.Channel 77 | defer db.Close() 78 | newChannel = model.Channel{ID: ID, Name: ""} 79 | for _, observer := range deleteChannelObserver { 80 | observer <- newChannel 81 | } 82 | return newChannel, nil 83 | } 84 | func (r *mutationResolver) UpdateChannel(ctx context.Context, id int, name string) (model.Channel, error) { 85 | db := connection.DbConn() 86 | 87 | insForm, err := db.Prepare("UPDATE channel SET name=? WHERE id=?") 88 | if err != nil { 89 | panic(err.Error()) 90 | } 91 | 92 | var newChannel model.Channel 93 | insForm.Exec(name, id) 94 | newChannel = model.Channel{ID: id, Name: name} 95 | 96 | defer db.Close() 97 | //add new chanel in observer 98 | for _, observer := range updateChannelObserver { 99 | observer <- newChannel 100 | } 101 | return newChannel, nil 102 | } 103 | 104 | func (r *subscriptionResolver) SubscriptionChannelAdded(ctx context.Context) (<-chan model.Channel, error) { 105 | id := randString(8) 106 | events := make(chan model.Channel, 1) 107 | 108 | go func() { 109 | <-ctx.Done() 110 | delete(addChannelObserver, id) 111 | }() 112 | 113 | addChannelObserver[id] = events 114 | 115 | return events, nil 116 | } 117 | 118 | func (r *subscriptionResolver) SubscriptionChannelDeleted(ctx context.Context) (<-chan model.Channel, error) { 119 | id := randString(8) 120 | events := make(chan model.Channel, 1) 121 | 122 | go func() { 123 | <-ctx.Done() 124 | delete(deleteChannelObserver, id) 125 | }() 126 | 127 | deleteChannelObserver[id] = events 128 | 129 | return events, nil 130 | } 131 | 132 | func (r *subscriptionResolver) SubscriptionChannelUpdated(ctx context.Context) (<-chan model.Channel, error) { 133 | id := randString(8) 134 | events := make(chan model.Channel, 1) 135 | 136 | go func() { 137 | <-ctx.Done() 138 | delete(updateChannelObserver, id) 139 | }() 140 | 141 | updateChannelObserver[id] = events 142 | 143 | return events, nil 144 | } 145 | -------------------------------------------------------------------------------- /golang/app/resolver/resolver.go: -------------------------------------------------------------------------------- 1 | //go:generate gorunpkg github.com/99designs/gqlgen 2 | 3 | package resolver 4 | 5 | import ( 6 | graph "golang-gqlgen-reactjs-subscription-demo/golang/app/graph" 7 | "math/rand" 8 | ) 9 | 10 | type Resolver struct{} 11 | 12 | func (r *Resolver) Mutation() graph.MutationResolver { 13 | return &mutationResolver{r} 14 | } 15 | func (r *Resolver) Query() graph.QueryResolver { 16 | return &queryResolver{r} 17 | } 18 | func (r *Resolver) Subscription() graph.SubscriptionResolver { 19 | return &subscriptionResolver{r} 20 | } 21 | 22 | type mutationResolver struct{ *Resolver } 23 | 24 | type queryResolver struct{ *Resolver } 25 | 26 | type subscriptionResolver struct{ *Resolver } 27 | 28 | var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") 29 | 30 | func randString(n int) string { 31 | b := make([]rune, n) 32 | for i := range b { 33 | b[i] = letterRunes[rand.Intn(len(letterRunes))] 34 | } 35 | return string(b) 36 | } 37 | -------------------------------------------------------------------------------- /golang/gqlgen.yml: -------------------------------------------------------------------------------- 1 | # .gqlgen.yml example 2 | # 3 | # Refer to https://gqlgen.com/config/ 4 | # for detailed .gqlgen.yml documentation. 5 | 6 | schema: schema.graphql 7 | exec: 8 | filename: app/graph/generated.go 9 | 10 | model: 11 | filename: app/model/models_gen.go 12 | 13 | resolver: 14 | filename: app/resolver/resolver.go 15 | type: Resolver 16 | -------------------------------------------------------------------------------- /golang/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | graph "golang-gqlgen-reactjs-subscription-demo/golang/app/graph" 5 | resolver "golang-gqlgen-reactjs-subscription-demo/golang/app/resolver" 6 | "log" 7 | "net/http" 8 | "os" 9 | 10 | "github.com/99designs/gqlgen/handler" 11 | gqlopentracing "github.com/99designs/gqlgen/opentracing" 12 | "github.com/gorilla/websocket" 13 | ) 14 | 15 | const defaultPort = "8888" 16 | 17 | func main() { 18 | port := os.Getenv("PORT") 19 | if port == "" { 20 | port = defaultPort 21 | } 22 | 23 | http.Handle("/", handler.Playground("GraphQL playground", "/query")) 24 | // http.Handle("/query", handler.GraphQL(graph.NewExecutableSchema(graph.Config{Resolvers: &resolver.Resolver{}}))) 25 | http.Handle("/query", corsAccess(handler.GraphQL(graph.NewExecutableSchema(graph.Config{Resolvers: &resolver.Resolver{}}), 26 | 27 | handler.ResolverMiddleware(gqlopentracing.ResolverMiddleware()), 28 | handler.RequestMiddleware(gqlopentracing.RequestMiddleware()), 29 | handler.WebsocketUpgrader(websocket.Upgrader{ 30 | CheckOrigin: func(r *http.Request) bool { 31 | return true 32 | }, 33 | }))), 34 | ) 35 | log.Printf("connect to http://localhost:%s/ for GraphQL playground", port) 36 | log.Fatal(http.ListenAndServe(":"+port, nil)) 37 | } 38 | func corsAccess(next http.HandlerFunc) http.HandlerFunc { 39 | return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 40 | w.Header().Set("Access-Control-Allow-Origin", "*") 41 | w.Header().Set("Access-Control-Allow-Credentials", "true") 42 | w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") 43 | w.Header().Set("Access-Control-Allow-Headers", 44 | "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization") 45 | if req.Method == "OPTIONS" { 46 | return 47 | } 48 | next(w, req) 49 | }) 50 | } 51 | -------------------------------------------------------------------------------- /golang/schema.graphql: -------------------------------------------------------------------------------- 1 | 2 | type Channel { 3 | id: Int! # "!" denotes a required field 4 | name: String! 5 | } 6 | 7 | type Query { 8 | channels: [Channel!]! 9 | } 10 | 11 | type Mutation { 12 | addChannel(name: String!): Channel! 13 | updateChannel(id:Int!,name: String!): Channel! 14 | deleteChannel(ID: Int!): Channel! 15 | } 16 | 17 | type Subscription { 18 | subscriptionChannelAdded: Channel! 19 | subscriptionChannelDeleted: Channel! 20 | subscriptionChannelUpdated: Channel! 21 | } 22 | -------------------------------------------------------------------------------- /reactjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chat", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "apollo-boost": "^0.1.15", 7 | "apollo-cache-inmemory": "^1.2.9", 8 | "apollo-client": "^2.4.1", 9 | "apollo-link-ws": "^1.0.8", 10 | "graphql": "^14.0.0", 11 | "graphql-tag": "^2.9.2", 12 | "jwt-decode": "^2.2.0", 13 | "react": "^16.4.2", 14 | "react-apollo": "^2.1.11", 15 | "react-autocomplete": "^1.8.1", 16 | "react-dom": "^16.4.2", 17 | "react-json-view": "^1.19.1", 18 | "react-scripts": "1.1.5", 19 | "subscriptions-transport-ws": "^0.9.14" 20 | }, 21 | "scripts": { 22 | "start": "react-scripts start", 23 | "build": "react-scripts build", 24 | "test": "react-scripts test --env=jsdom", 25 | "eject": "react-scripts eject" 26 | }, 27 | "devDependencies": { 28 | "axios": "^0.18.0", 29 | "react-addons-update": "^15.6.2", 30 | "react-router-dom": "^4.3.1", 31 | "underscore": "^1.9.1" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /reactjs/public/css/dataTables.bootstrap4.min.css: -------------------------------------------------------------------------------- 1 | table.dataTable{clear:both;margin-top:6px !important;margin-bottom:6px !important;max-width:none !important;border-collapse:separate !important;border-spacing:0}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}div.dataTables_wrapper div.dataTables_length label{font-weight:normal;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:auto;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:normal;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:0.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:0.85em;white-space:nowrap}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap;justify-content:flex-end}div.dataTables_wrapper div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:1em 0}table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting{padding-right:30px}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{cursor:pointer;position:relative}table.dataTable thead .sorting:before,table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:before,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:before,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:before,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:before,table.dataTable thead .sorting_desc_disabled:after{position:absolute;bottom:0.9em;display:block;opacity:0.3}table.dataTable thead .sorting:before,table.dataTable thead .sorting_asc:before,table.dataTable thead .sorting_desc:before,table.dataTable thead .sorting_asc_disabled:before,table.dataTable thead .sorting_desc_disabled:before{right:1em;content:"\2191"}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{right:0.5em;content:"\2193"}table.dataTable thead .sorting_asc:before,table.dataTable thead .sorting_desc:after{opacity:1}table.dataTable thead .sorting_asc_disabled:before,table.dataTable thead .sorting_desc_disabled:after{opacity:0}div.dataTables_scrollHead table.dataTable{margin-bottom:0 !important}div.dataTables_scrollBody table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody table thead .sorting:before,div.dataTables_scrollBody table thead .sorting_asc:before,div.dataTables_scrollBody table thead .sorting_desc:before,div.dataTables_scrollBody table thead .sorting:after,div.dataTables_scrollBody table thead .sorting_asc:after,div.dataTables_scrollBody table thead .sorting_desc:after{display:none}div.dataTables_scrollBody table tbody tr:first-child th,div.dataTables_scrollBody table tbody tr:first-child td{border-top:none}div.dataTables_scrollFoot>.dataTables_scrollFootInner{box-sizing:content-box}div.dataTables_scrollFoot>.dataTables_scrollFootInner>table{margin-top:0 !important;border-top:none}@media screen and (max-width: 767px){div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_paginate{text-align:center}}table.dataTable.table-sm>thead>tr>th{padding-right:20px}table.dataTable.table-sm .sorting:before,table.dataTable.table-sm .sorting_asc:before,table.dataTable.table-sm .sorting_desc:before{top:5px;right:0.85em}table.dataTable.table-sm .sorting:after,table.dataTable.table-sm .sorting_asc:after,table.dataTable.table-sm .sorting_desc:after{top:5px}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-left-width:0}table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable td:last-child{border-right-width:0}table.table-bordered.dataTable tbody th,table.table-bordered.dataTable tbody td{border-bottom-width:0}div.dataTables_scrollHead table.table-bordered{border-bottom-width:0}div.table-responsive>div.dataTables_wrapper>div.row{margin:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:first-child{padding-left:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:last-child{padding-right:0} 2 | -------------------------------------------------------------------------------- /reactjs/public/css/datatables.min.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This combined file was created by the DataTables downloader builder: 3 | * https://datatables.net/download 4 | * 5 | * To rebuild or modify this file with the latest versions of the included 6 | * software please visit: 7 | * https://datatables.net/download/#bs4/dt-1.10.18/r-2.2.2 8 | * 9 | * Included libraries: 10 | * DataTables 1.10.18, Responsive 2.2.2 11 | */ 12 | 13 | table.dataTable{clear:both;margin-top:6px !important;margin-bottom:6px !important;max-width:none !important;border-collapse:separate !important;border-spacing:0}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}div.dataTables_wrapper div.dataTables_length label{font-weight:normal;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:auto;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:normal;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:0.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:0.85em;white-space:nowrap}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap;justify-content:flex-end}div.dataTables_wrapper div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:1em 0}table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting{padding-right:30px}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{cursor:pointer;position:relative}table.dataTable thead .sorting:before,table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:before,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:before,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:before,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:before,table.dataTable thead .sorting_desc_disabled:after{position:absolute;bottom:0.9em;display:block;opacity:0.3}table.dataTable thead .sorting:before,table.dataTable thead .sorting_asc:before,table.dataTable thead .sorting_desc:before,table.dataTable thead .sorting_asc_disabled:before,table.dataTable thead .sorting_desc_disabled:before{right:1em;content:"\2191"}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{right:0.5em;content:"\2193"}table.dataTable thead .sorting_asc:before,table.dataTable thead .sorting_desc:after{opacity:1}table.dataTable thead .sorting_asc_disabled:before,table.dataTable thead .sorting_desc_disabled:after{opacity:0}div.dataTables_scrollHead table.dataTable{margin-bottom:0 !important}div.dataTables_scrollBody table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody table thead .sorting:before,div.dataTables_scrollBody table thead .sorting_asc:before,div.dataTables_scrollBody table thead .sorting_desc:before,div.dataTables_scrollBody table thead .sorting:after,div.dataTables_scrollBody table thead .sorting_asc:after,div.dataTables_scrollBody table thead .sorting_desc:after{display:none}div.dataTables_scrollBody table tbody tr:first-child th,div.dataTables_scrollBody table tbody tr:first-child td{border-top:none}div.dataTables_scrollFoot>.dataTables_scrollFootInner{box-sizing:content-box}div.dataTables_scrollFoot>.dataTables_scrollFootInner>table{margin-top:0 !important;border-top:none}@media screen and (max-width: 767px){div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_paginate{text-align:center}}table.dataTable.table-sm>thead>tr>th{padding-right:20px}table.dataTable.table-sm .sorting:before,table.dataTable.table-sm .sorting_asc:before,table.dataTable.table-sm .sorting_desc:before{top:5px;right:0.85em}table.dataTable.table-sm .sorting:after,table.dataTable.table-sm .sorting_asc:after,table.dataTable.table-sm .sorting_desc:after{top:5px}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-left-width:0}table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable td:last-child{border-right-width:0}table.table-bordered.dataTable tbody th,table.table-bordered.dataTable tbody td{border-bottom-width:0}div.dataTables_scrollHead table.table-bordered{border-bottom-width:0}div.table-responsive>div.dataTables_wrapper>div.row{margin:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:first-child{padding-left:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:last-child{padding-right:0} 14 | 15 | 16 | table.dataTable.dtr-inline.collapsed>tbody>tr>td.child,table.dataTable.dtr-inline.collapsed>tbody>tr>th.child,table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty{cursor:default !important}table.dataTable.dtr-inline.collapsed>tbody>tr>td.child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>th.child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty:before{display:none !important}table.dataTable.dtr-inline.collapsed>tbody>tr[role="row"]>td:first-child,table.dataTable.dtr-inline.collapsed>tbody>tr[role="row"]>th:first-child{position:relative;padding-left:30px;cursor:pointer}table.dataTable.dtr-inline.collapsed>tbody>tr[role="row"]>td:first-child:before,table.dataTable.dtr-inline.collapsed>tbody>tr[role="row"]>th:first-child:before{top:12px;left:4px;height:14px;width:14px;display:block;position:absolute;color:white;border:2px solid white;border-radius:14px;box-shadow:0 0 3px #444;box-sizing:content-box;text-align:center;text-indent:0 !important;font-family:'Courier New', Courier, monospace;line-height:14px;content:'+';background-color:#0275d8}table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td:first-child:before,table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th:first-child:before{content:'-';background-color:#d33333}table.dataTable.dtr-inline.collapsed.compact>tbody>tr>td:first-child,table.dataTable.dtr-inline.collapsed.compact>tbody>tr>th:first-child{padding-left:27px}table.dataTable.dtr-inline.collapsed.compact>tbody>tr>td:first-child:before,table.dataTable.dtr-inline.collapsed.compact>tbody>tr>th:first-child:before{top:5px;left:4px;height:14px;width:14px;border-radius:14px;line-height:14px;text-indent:3px}table.dataTable.dtr-column>tbody>tr>td.control,table.dataTable.dtr-column>tbody>tr>th.control{position:relative;cursor:pointer}table.dataTable.dtr-column>tbody>tr>td.control:before,table.dataTable.dtr-column>tbody>tr>th.control:before{top:50%;left:50%;height:16px;width:16px;margin-top:-10px;margin-left:-10px;display:block;position:absolute;color:white;border:2px solid white;border-radius:14px;box-shadow:0 0 3px #444;box-sizing:content-box;text-align:center;text-indent:0 !important;font-family:'Courier New', Courier, monospace;line-height:14px;content:'+';background-color:#0275d8}table.dataTable.dtr-column>tbody>tr.parent td.control:before,table.dataTable.dtr-column>tbody>tr.parent th.control:before{content:'-';background-color:#d33333}table.dataTable>tbody>tr.child{padding:0.5em 1em}table.dataTable>tbody>tr.child:hover{background:transparent !important}table.dataTable>tbody>tr.child ul.dtr-details{display:inline-block;list-style-type:none;margin:0;padding:0}table.dataTable>tbody>tr.child ul.dtr-details>li{border-bottom:1px solid #efefef;padding:0.5em 0}table.dataTable>tbody>tr.child ul.dtr-details>li:first-child{padding-top:0}table.dataTable>tbody>tr.child ul.dtr-details>li:last-child{border-bottom:none}table.dataTable>tbody>tr.child span.dtr-title{display:inline-block;min-width:75px;font-weight:bold}div.dtr-modal{position:fixed;box-sizing:border-box;top:0;left:0;height:100%;width:100%;z-index:100;padding:10em 1em}div.dtr-modal div.dtr-modal-display{position:absolute;top:0;left:0;bottom:0;right:0;width:50%;height:50%;overflow:auto;margin:auto;z-index:102;overflow:auto;background-color:#f5f5f7;border:1px solid black;border-radius:0.5em;box-shadow:0 12px 30px rgba(0,0,0,0.6)}div.dtr-modal div.dtr-modal-content{position:relative;padding:1em}div.dtr-modal div.dtr-modal-close{position:absolute;top:6px;right:6px;width:22px;height:22px;border:1px solid #eaeaea;background-color:#f9f9f9;text-align:center;border-radius:3px;cursor:pointer;z-index:12}div.dtr-modal div.dtr-modal-close:hover{background-color:#eaeaea}div.dtr-modal div.dtr-modal-background{position:fixed;top:0;left:0;right:0;bottom:0;z-index:101;background:rgba(0,0,0,0.6)}@media screen and (max-width: 767px){div.dtr-modal div.dtr-modal-display{width:95%}}div.dtr-bs-modal table.table tr:first-child td{border-top:none} 17 | 18 | 19 | -------------------------------------------------------------------------------- /reactjs/public/css/loader.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | .lds-roller { 4 | display: inline-block; 5 | position: relative; 6 | width: 64px; 7 | height: 64px; 8 | top:250px 9 | } 10 | .lds-roller div { 11 | animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; 12 | transform-origin: 32px 32px; 13 | } 14 | .lds-roller div:after { 15 | content: " "; 16 | display: block; 17 | position: absolute; 18 | width: 6px; 19 | height: 6px; 20 | border-radius: 50%; 21 | background: black; 22 | margin: -3px 0 0 -3px; 23 | } 24 | .lds-roller div:nth-child(1) { 25 | animation-delay: -0.036s; 26 | } 27 | .lds-roller div:nth-child(1):after { 28 | top: 50px; 29 | left: 50px; 30 | } 31 | .lds-roller div:nth-child(2) { 32 | animation-delay: -0.072s; 33 | } 34 | .lds-roller div:nth-child(2):after { 35 | top: 54px; 36 | left: 45px; 37 | } 38 | .lds-roller div:nth-child(3) { 39 | animation-delay: -0.108s; 40 | } 41 | .lds-roller div:nth-child(3):after { 42 | top: 57px; 43 | left: 39px; 44 | } 45 | .lds-roller div:nth-child(4) { 46 | animation-delay: -0.144s; 47 | } 48 | .lds-roller div:nth-child(4):after { 49 | top: 58px; 50 | left: 32px; 51 | } 52 | .lds-roller div:nth-child(5) { 53 | animation-delay: -0.18s; 54 | } 55 | .lds-roller div:nth-child(5):after { 56 | top: 57px; 57 | left: 25px; 58 | } 59 | .lds-roller div:nth-child(6) { 60 | animation-delay: -0.216s; 61 | } 62 | .lds-roller div:nth-child(6):after { 63 | top: 54px; 64 | left: 19px; 65 | } 66 | .lds-roller div:nth-child(7) { 67 | animation-delay: -0.252s; 68 | } 69 | .lds-roller div:nth-child(7):after { 70 | top: 50px; 71 | left: 14px; 72 | } 73 | .lds-roller div:nth-child(8) { 74 | animation-delay: -0.288s; 75 | } 76 | .lds-roller div:nth-child(8):after { 77 | top: 45px; 78 | left: 10px; 79 | } 80 | @keyframes lds-roller { 81 | 0% { 82 | transform: rotate(0deg); 83 | } 84 | 100% { 85 | transform: rotate(360deg); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /reactjs/public/img/3pl-logo-600.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logisticinfotech/golang-gqlgen-reactjs-subscription-demo/003342486bfe2767bdfe3cda11474a5d7f669b3a/reactjs/public/img/3pl-logo-600.png -------------------------------------------------------------------------------- /reactjs/public/img/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logisticinfotech/golang-gqlgen-reactjs-subscription-demo/003342486bfe2767bdfe3cda11474a5d7f669b3a/reactjs/public/img/favicon-16x16.png -------------------------------------------------------------------------------- /reactjs/public/img/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logisticinfotech/golang-gqlgen-reactjs-subscription-demo/003342486bfe2767bdfe3cda11474a5d7f669b3a/reactjs/public/img/favicon-32x32.png -------------------------------------------------------------------------------- /reactjs/public/img/green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logisticinfotech/golang-gqlgen-reactjs-subscription-demo/003342486bfe2767bdfe3cda11474a5d7f669b3a/reactjs/public/img/green.png -------------------------------------------------------------------------------- /reactjs/public/img/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logisticinfotech/golang-gqlgen-reactjs-subscription-demo/003342486bfe2767bdfe3cda11474a5d7f669b3a/reactjs/public/img/red.png -------------------------------------------------------------------------------- /reactjs/public/img/yellow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logisticinfotech/golang-gqlgen-reactjs-subscription-demo/003342486bfe2767bdfe3cda11474a5d7f669b3a/reactjs/public/img/yellow.jpg -------------------------------------------------------------------------------- /reactjs/public/img/yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/logisticinfotech/golang-gqlgen-reactjs-subscription-demo/003342486bfe2767bdfe3cda11474a5d7f669b3a/reactjs/public/img/yellow.png -------------------------------------------------------------------------------- /reactjs/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | React App 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 |
27 | 28 | 29 | -------------------------------------------------------------------------------- /reactjs/public/js/bootstrap.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v4.0.0 (https://getbootstrap.com) 3 | * Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 5 | */ 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e(t.bootstrap={},t.jQuery,t.Popper)}(this,function(t,e,n){"use strict";function i(t,e){for(var n=0;n0?i:null}catch(t){return null}},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(n){t(n).trigger(e.end)},supportsTransitionEnd:function(){return Boolean(e)},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var s in n)if(Object.prototype.hasOwnProperty.call(n,s)){var r=n[s],o=e[s],a=o&&i.isElement(o)?"element":(l=o,{}.toString.call(l).match(/\s([a-zA-Z]+)/)[1].toLowerCase());if(!new RegExp(r).test(a))throw new Error(t.toUpperCase()+': Option "'+s+'" provided type "'+a+'" but expected type "'+r+'".')}var l}};return e=("undefined"==typeof window||!window.QUnit)&&{end:"transitionend"},t.fn.emulateTransitionEnd=n,i.supportsTransitionEnd()&&(t.event.special[i.TRANSITION_END]={bindType:e.end,delegateType:e.end,handle:function(e){if(t(e.target).is(this))return e.handleObj.handler.apply(this,arguments)}}),i}(e),L=(a="alert",h="."+(l="bs.alert"),c=(o=e).fn[a],u={CLOSE:"close"+h,CLOSED:"closed"+h,CLICK_DATA_API:"click"+h+".data-api"},f="alert",d="fade",_="show",g=function(){function t(t){this._element=t}var e=t.prototype;return e.close=function(t){t=t||this._element;var e=this._getRootElement(t);this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){o.removeData(this._element,l),this._element=null},e._getRootElement=function(t){var e=P.getSelectorFromElement(t),n=!1;return e&&(n=o(e)[0]),n||(n=o(t).closest("."+f)[0]),n},e._triggerCloseEvent=function(t){var e=o.Event(u.CLOSE);return o(t).trigger(e),e},e._removeElement=function(t){var e=this;o(t).removeClass(_),P.supportsTransitionEnd()&&o(t).hasClass(d)?o(t).one(P.TRANSITION_END,function(n){return e._destroyElement(t,n)}).emulateTransitionEnd(150):this._destroyElement(t)},e._destroyElement=function(t){o(t).detach().trigger(u.CLOSED).remove()},t._jQueryInterface=function(e){return this.each(function(){var n=o(this),i=n.data(l);i||(i=new t(this),n.data(l,i)),"close"===e&&i[e](this)})},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},s(t,null,[{key:"VERSION",get:function(){return"4.0.0"}}]),t}(),o(document).on(u.CLICK_DATA_API,'[data-dismiss="alert"]',g._handleDismiss(new g)),o.fn[a]=g._jQueryInterface,o.fn[a].Constructor=g,o.fn[a].noConflict=function(){return o.fn[a]=c,g._jQueryInterface},g),R=(m="button",E="."+(v="bs.button"),T=".data-api",y=(p=e).fn[m],C="active",I="btn",A="focus",b='[data-toggle^="button"]',D='[data-toggle="buttons"]',S="input",w=".active",N=".btn",O={CLICK_DATA_API:"click"+E+T,FOCUS_BLUR_DATA_API:"focus"+E+T+" blur"+E+T},k=function(){function t(t){this._element=t}var e=t.prototype;return e.toggle=function(){var t=!0,e=!0,n=p(this._element).closest(D)[0];if(n){var i=p(this._element).find(S)[0];if(i){if("radio"===i.type)if(i.checked&&p(this._element).hasClass(C))t=!1;else{var s=p(n).find(w)[0];s&&p(s).removeClass(C)}if(t){if(i.hasAttribute("disabled")||n.hasAttribute("disabled")||i.classList.contains("disabled")||n.classList.contains("disabled"))return;i.checked=!p(this._element).hasClass(C),p(i).trigger("change")}i.focus(),e=!1}}e&&this._element.setAttribute("aria-pressed",!p(this._element).hasClass(C)),t&&p(this._element).toggleClass(C)},e.dispose=function(){p.removeData(this._element,v),this._element=null},t._jQueryInterface=function(e){return this.each(function(){var n=p(this).data(v);n||(n=new t(this),p(this).data(v,n)),"toggle"===e&&n[e]()})},s(t,null,[{key:"VERSION",get:function(){return"4.0.0"}}]),t}(),p(document).on(O.CLICK_DATA_API,b,function(t){t.preventDefault();var e=t.target;p(e).hasClass(I)||(e=p(e).closest(N)),k._jQueryInterface.call(p(e),"toggle")}).on(O.FOCUS_BLUR_DATA_API,b,function(t){var e=p(t.target).closest(N)[0];p(e).toggleClass(A,/^focus(in)?$/.test(t.type))}),p.fn[m]=k._jQueryInterface,p.fn[m].Constructor=k,p.fn[m].noConflict=function(){return p.fn[m]=y,k._jQueryInterface},k),j=function(t){var e="carousel",n="bs.carousel",i="."+n,o=t.fn[e],a={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0},l={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean"},h="next",c="prev",u="left",f="right",d={SLIDE:"slide"+i,SLID:"slid"+i,KEYDOWN:"keydown"+i,MOUSEENTER:"mouseenter"+i,MOUSELEAVE:"mouseleave"+i,TOUCHEND:"touchend"+i,LOAD_DATA_API:"load"+i+".data-api",CLICK_DATA_API:"click"+i+".data-api"},_="carousel",g="active",p="slide",m="carousel-item-right",v="carousel-item-left",E="carousel-item-next",T="carousel-item-prev",y={ACTIVE:".active",ACTIVE_ITEM:".active.carousel-item",ITEM:".carousel-item",NEXT_PREV:".carousel-item-next, .carousel-item-prev",INDICATORS:".carousel-indicators",DATA_SLIDE:"[data-slide], [data-slide-to]",DATA_RIDE:'[data-ride="carousel"]'},C=function(){function o(e,n){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this._config=this._getConfig(n),this._element=t(e)[0],this._indicatorsElement=t(this._element).find(y.INDICATORS)[0],this._addEventListeners()}var C=o.prototype;return C.next=function(){this._isSliding||this._slide(h)},C.nextWhenVisible=function(){!document.hidden&&t(this._element).is(":visible")&&"hidden"!==t(this._element).css("visibility")&&this.next()},C.prev=function(){this._isSliding||this._slide(c)},C.pause=function(e){e||(this._isPaused=!0),t(this._element).find(y.NEXT_PREV)[0]&&P.supportsTransitionEnd()&&(P.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},C.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},C.to=function(e){var n=this;this._activeElement=t(this._element).find(y.ACTIVE_ITEM)[0];var i=this._getItemIndex(this._activeElement);if(!(e>this._items.length-1||e<0))if(this._isSliding)t(this._element).one(d.SLID,function(){return n.to(e)});else{if(i===e)return this.pause(),void this.cycle();var s=e>i?h:c;this._slide(s,this._items[e])}},C.dispose=function(){t(this._element).off(i),t.removeData(this._element,n),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},C._getConfig=function(t){return t=r({},a,t),P.typeCheckConfig(e,t,l),t},C._addEventListeners=function(){var e=this;this._config.keyboard&&t(this._element).on(d.KEYDOWN,function(t){return e._keydown(t)}),"hover"===this._config.pause&&(t(this._element).on(d.MOUSEENTER,function(t){return e.pause(t)}).on(d.MOUSELEAVE,function(t){return e.cycle(t)}),"ontouchstart"in document.documentElement&&t(this._element).on(d.TOUCHEND,function(){e.pause(),e.touchTimeout&&clearTimeout(e.touchTimeout),e.touchTimeout=setTimeout(function(t){return e.cycle(t)},500+e._config.interval)}))},C._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},C._getItemIndex=function(e){return this._items=t.makeArray(t(e).parent().find(y.ITEM)),this._items.indexOf(e)},C._getItemByDirection=function(t,e){var n=t===h,i=t===c,s=this._getItemIndex(e),r=this._items.length-1;if((i&&0===s||n&&s===r)&&!this._config.wrap)return e;var o=(s+(t===c?-1:1))%this._items.length;return-1===o?this._items[this._items.length-1]:this._items[o]},C._triggerSlideEvent=function(e,n){var i=this._getItemIndex(e),s=this._getItemIndex(t(this._element).find(y.ACTIVE_ITEM)[0]),r=t.Event(d.SLIDE,{relatedTarget:e,direction:n,from:s,to:i});return t(this._element).trigger(r),r},C._setActiveIndicatorElement=function(e){if(this._indicatorsElement){t(this._indicatorsElement).find(y.ACTIVE).removeClass(g);var n=this._indicatorsElement.children[this._getItemIndex(e)];n&&t(n).addClass(g)}},C._slide=function(e,n){var i,s,r,o=this,a=t(this._element).find(y.ACTIVE_ITEM)[0],l=this._getItemIndex(a),c=n||a&&this._getItemByDirection(e,a),_=this._getItemIndex(c),C=Boolean(this._interval);if(e===h?(i=v,s=E,r=u):(i=m,s=T,r=f),c&&t(c).hasClass(g))this._isSliding=!1;else if(!this._triggerSlideEvent(c,r).isDefaultPrevented()&&a&&c){this._isSliding=!0,C&&this.pause(),this._setActiveIndicatorElement(c);var I=t.Event(d.SLID,{relatedTarget:c,direction:r,from:l,to:_});P.supportsTransitionEnd()&&t(this._element).hasClass(p)?(t(c).addClass(s),P.reflow(c),t(a).addClass(i),t(c).addClass(i),t(a).one(P.TRANSITION_END,function(){t(c).removeClass(i+" "+s).addClass(g),t(a).removeClass(g+" "+s+" "+i),o._isSliding=!1,setTimeout(function(){return t(o._element).trigger(I)},0)}).emulateTransitionEnd(600)):(t(a).removeClass(g),t(c).addClass(g),this._isSliding=!1,t(this._element).trigger(I)),C&&this.cycle()}},o._jQueryInterface=function(e){return this.each(function(){var i=t(this).data(n),s=r({},a,t(this).data());"object"==typeof e&&(s=r({},s,e));var l="string"==typeof e?e:s.slide;if(i||(i=new o(this,s),t(this).data(n,i)),"number"==typeof e)i.to(e);else if("string"==typeof l){if("undefined"==typeof i[l])throw new TypeError('No method named "'+l+'"');i[l]()}else s.interval&&(i.pause(),i.cycle())})},o._dataApiClickHandler=function(e){var i=P.getSelectorFromElement(this);if(i){var s=t(i)[0];if(s&&t(s).hasClass(_)){var a=r({},t(s).data(),t(this).data()),l=this.getAttribute("data-slide-to");l&&(a.interval=!1),o._jQueryInterface.call(t(s),a),l&&t(s).data(n).to(l),e.preventDefault()}}},s(o,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return a}}]),o}();return t(document).on(d.CLICK_DATA_API,y.DATA_SLIDE,C._dataApiClickHandler),t(window).on(d.LOAD_DATA_API,function(){t(y.DATA_RIDE).each(function(){var e=t(this);C._jQueryInterface.call(e,e.data())})}),t.fn[e]=C._jQueryInterface,t.fn[e].Constructor=C,t.fn[e].noConflict=function(){return t.fn[e]=o,C._jQueryInterface},C}(e),H=function(t){var e="collapse",n="bs.collapse",i="."+n,o=t.fn[e],a={toggle:!0,parent:""},l={toggle:"boolean",parent:"(string|element)"},h={SHOW:"show"+i,SHOWN:"shown"+i,HIDE:"hide"+i,HIDDEN:"hidden"+i,CLICK_DATA_API:"click"+i+".data-api"},c="show",u="collapse",f="collapsing",d="collapsed",_="width",g="height",p={ACTIVES:".show, .collapsing",DATA_TOGGLE:'[data-toggle="collapse"]'},m=function(){function i(e,n){this._isTransitioning=!1,this._element=e,this._config=this._getConfig(n),this._triggerArray=t.makeArray(t('[data-toggle="collapse"][href="#'+e.id+'"],[data-toggle="collapse"][data-target="#'+e.id+'"]'));for(var i=t(p.DATA_TOGGLE),s=0;s0&&(this._selector=o,this._triggerArray.push(r))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var o=i.prototype;return o.toggle=function(){t(this._element).hasClass(c)?this.hide():this.show()},o.show=function(){var e,s,r=this;if(!this._isTransitioning&&!t(this._element).hasClass(c)&&(this._parent&&0===(e=t.makeArray(t(this._parent).find(p.ACTIVES).filter('[data-parent="'+this._config.parent+'"]'))).length&&(e=null),!(e&&(s=t(e).not(this._selector).data(n))&&s._isTransitioning))){var o=t.Event(h.SHOW);if(t(this._element).trigger(o),!o.isDefaultPrevented()){e&&(i._jQueryInterface.call(t(e).not(this._selector),"hide"),s||t(e).data(n,null));var a=this._getDimension();t(this._element).removeClass(u).addClass(f),this._element.style[a]=0,this._triggerArray.length>0&&t(this._triggerArray).removeClass(d).attr("aria-expanded",!0),this.setTransitioning(!0);var l=function(){t(r._element).removeClass(f).addClass(u).addClass(c),r._element.style[a]="",r.setTransitioning(!1),t(r._element).trigger(h.SHOWN)};if(P.supportsTransitionEnd()){var _="scroll"+(a[0].toUpperCase()+a.slice(1));t(this._element).one(P.TRANSITION_END,l).emulateTransitionEnd(600),this._element.style[a]=this._element[_]+"px"}else l()}}},o.hide=function(){var e=this;if(!this._isTransitioning&&t(this._element).hasClass(c)){var n=t.Event(h.HIDE);if(t(this._element).trigger(n),!n.isDefaultPrevented()){var i=this._getDimension();if(this._element.style[i]=this._element.getBoundingClientRect()[i]+"px",P.reflow(this._element),t(this._element).addClass(f).removeClass(u).removeClass(c),this._triggerArray.length>0)for(var s=0;s0&&t(n).toggleClass(d,!i).attr("aria-expanded",i)}},i._getTargetFromElement=function(e){var n=P.getSelectorFromElement(e);return n?t(n)[0]:null},i._jQueryInterface=function(e){return this.each(function(){var s=t(this),o=s.data(n),l=r({},a,s.data(),"object"==typeof e&&e);if(!o&&l.toggle&&/show|hide/.test(e)&&(l.toggle=!1),o||(o=new i(this,l),s.data(n,o)),"string"==typeof e){if("undefined"==typeof o[e])throw new TypeError('No method named "'+e+'"');o[e]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return a}}]),i}();return t(document).on(h.CLICK_DATA_API,p.DATA_TOGGLE,function(e){"A"===e.currentTarget.tagName&&e.preventDefault();var i=t(this),s=P.getSelectorFromElement(this);t(s).each(function(){var e=t(this),s=e.data(n)?"toggle":i.data();m._jQueryInterface.call(e,s)})}),t.fn[e]=m._jQueryInterface,t.fn[e].Constructor=m,t.fn[e].noConflict=function(){return t.fn[e]=o,m._jQueryInterface},m}(e),W=function(t){var e="dropdown",i="bs.dropdown",o="."+i,a=".data-api",l=t.fn[e],h=new RegExp("38|40|27"),c={HIDE:"hide"+o,HIDDEN:"hidden"+o,SHOW:"show"+o,SHOWN:"shown"+o,CLICK:"click"+o,CLICK_DATA_API:"click"+o+a,KEYDOWN_DATA_API:"keydown"+o+a,KEYUP_DATA_API:"keyup"+o+a},u="disabled",f="show",d="dropup",_="dropright",g="dropleft",p="dropdown-menu-right",m="dropdown-menu-left",v="position-static",E='[data-toggle="dropdown"]',T=".dropdown form",y=".dropdown-menu",C=".navbar-nav",I=".dropdown-menu .dropdown-item:not(.disabled)",A="top-start",b="top-end",D="bottom-start",S="bottom-end",w="right-start",N="left-start",O={offset:0,flip:!0,boundary:"scrollParent"},k={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)"},L=function(){function a(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var l=a.prototype;return l.toggle=function(){if(!this._element.disabled&&!t(this._element).hasClass(u)){var e=a._getParentFromElement(this._element),i=t(this._menu).hasClass(f);if(a._clearMenus(),!i){var s={relatedTarget:this._element},r=t.Event(c.SHOW,s);if(t(e).trigger(r),!r.isDefaultPrevented()){if(!this._inNavbar){if("undefined"==typeof n)throw new TypeError("Bootstrap dropdown require Popper.js (https://popper.js.org)");var o=this._element;t(e).hasClass(d)&&(t(this._menu).hasClass(m)||t(this._menu).hasClass(p))&&(o=e),"scrollParent"!==this._config.boundary&&t(e).addClass(v),this._popper=new n(o,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===t(e).closest(C).length&&t("body").children().on("mouseover",null,t.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),t(this._menu).toggleClass(f),t(e).toggleClass(f).trigger(t.Event(c.SHOWN,s))}}}},l.dispose=function(){t.removeData(this._element,i),t(this._element).off(o),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},l.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},l._addEventListeners=function(){var e=this;t(this._element).on(c.CLICK,function(t){t.preventDefault(),t.stopPropagation(),e.toggle()})},l._getConfig=function(n){return n=r({},this.constructor.Default,t(this._element).data(),n),P.typeCheckConfig(e,n,this.constructor.DefaultType),n},l._getMenuElement=function(){if(!this._menu){var e=a._getParentFromElement(this._element);this._menu=t(e).find(y)[0]}return this._menu},l._getPlacement=function(){var e=t(this._element).parent(),n=D;return e.hasClass(d)?(n=A,t(this._menu).hasClass(p)&&(n=b)):e.hasClass(_)?n=w:e.hasClass(g)?n=N:t(this._menu).hasClass(p)&&(n=S),n},l._detectNavbar=function(){return t(this._element).closest(".navbar").length>0},l._getPopperConfig=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t._config.offset(e.offsets)||{}),e}:e.offset=this._config.offset,{placement:this._getPlacement(),modifiers:{offset:e,flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}}},a._jQueryInterface=function(e){return this.each(function(){var n=t(this).data(i);if(n||(n=new a(this,"object"==typeof e?e:null),t(this).data(i,n)),"string"==typeof e){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}})},a._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var n=t.makeArray(t(E)),s=0;s0&&r--,40===e.which&&rdocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},p._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},p._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent"},f="show",d="out",_={HIDE:"hide"+o,HIDDEN:"hidden"+o,SHOW:"show"+o,SHOWN:"shown"+o,INSERTED:"inserted"+o,CLICK:"click"+o,FOCUSIN:"focusin"+o,FOCUSOUT:"focusout"+o,MOUSEENTER:"mouseenter"+o,MOUSELEAVE:"mouseleave"+o},g="fade",p="show",m=".tooltip-inner",v=".arrow",E="hover",T="focus",y="click",C="manual",I=function(){function a(t,e){if("undefined"==typeof n)throw new TypeError("Bootstrap tooltips require Popper.js (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var I=a.prototype;return I.enable=function(){this._isEnabled=!0},I.disable=function(){this._isEnabled=!1},I.toggleEnabled=function(){this._isEnabled=!this._isEnabled},I.toggle=function(e){if(this._isEnabled)if(e){var n=this.constructor.DATA_KEY,i=t(e.currentTarget).data(n);i||(i=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(n,i)),i._activeTrigger.click=!i._activeTrigger.click,i._isWithActiveTrigger()?i._enter(null,i):i._leave(null,i)}else{if(t(this.getTipElement()).hasClass(p))return void this._leave(null,this);this._enter(null,this)}},I.dispose=function(){clearTimeout(this._timeout),t.removeData(this.element,this.constructor.DATA_KEY),t(this.element).off(this.constructor.EVENT_KEY),t(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&t(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,null!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},I.show=function(){var e=this;if("none"===t(this.element).css("display"))throw new Error("Please use show on visible elements");var i=t.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){t(this.element).trigger(i);var s=t.contains(this.element.ownerDocument.documentElement,this.element);if(i.isDefaultPrevented()||!s)return;var r=this.getTipElement(),o=P.getUID(this.constructor.NAME);r.setAttribute("id",o),this.element.setAttribute("aria-describedby",o),this.setContent(),this.config.animation&&t(r).addClass(g);var l="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,h=this._getAttachment(l);this.addAttachmentClass(h);var c=!1===this.config.container?document.body:t(this.config.container);t(r).data(this.constructor.DATA_KEY,this),t.contains(this.element.ownerDocument.documentElement,this.tip)||t(r).appendTo(c),t(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new n(this.element,r,{placement:h,modifiers:{offset:{offset:this.config.offset},flip:{behavior:this.config.fallbackPlacement},arrow:{element:v},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){e._handlePopperPlacementChange(t)}}),t(r).addClass(p),"ontouchstart"in document.documentElement&&t("body").children().on("mouseover",null,t.noop);var u=function(){e.config.animation&&e._fixTransition();var n=e._hoverState;e._hoverState=null,t(e.element).trigger(e.constructor.Event.SHOWN),n===d&&e._leave(null,e)};P.supportsTransitionEnd()&&t(this.tip).hasClass(g)?t(this.tip).one(P.TRANSITION_END,u).emulateTransitionEnd(a._TRANSITION_DURATION):u()}},I.hide=function(e){var n=this,i=this.getTipElement(),s=t.Event(this.constructor.Event.HIDE),r=function(){n._hoverState!==f&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),t(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),e&&e()};t(this.element).trigger(s),s.isDefaultPrevented()||(t(i).removeClass(p),"ontouchstart"in document.documentElement&&t("body").children().off("mouseover",null,t.noop),this._activeTrigger[y]=!1,this._activeTrigger[T]=!1,this._activeTrigger[E]=!1,P.supportsTransitionEnd()&&t(this.tip).hasClass(g)?t(i).one(P.TRANSITION_END,r).emulateTransitionEnd(150):r(),this._hoverState="")},I.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},I.isWithContent=function(){return Boolean(this.getTitle())},I.addAttachmentClass=function(e){t(this.getTipElement()).addClass("bs-tooltip-"+e)},I.getTipElement=function(){return this.tip=this.tip||t(this.config.template)[0],this.tip},I.setContent=function(){var e=t(this.getTipElement());this.setElementContent(e.find(m),this.getTitle()),e.removeClass(g+" "+p)},I.setElementContent=function(e,n){var i=this.config.html;"object"==typeof n&&(n.nodeType||n.jquery)?i?t(n).parent().is(e)||e.empty().append(n):e.text(t(n).text()):e[i?"html":"text"](n)},I.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},I._getAttachment=function(t){return c[t.toUpperCase()]},I._setListeners=function(){var e=this;this.config.trigger.split(" ").forEach(function(n){if("click"===n)t(e.element).on(e.constructor.Event.CLICK,e.config.selector,function(t){return e.toggle(t)});else if(n!==C){var i=n===E?e.constructor.Event.MOUSEENTER:e.constructor.Event.FOCUSIN,s=n===E?e.constructor.Event.MOUSELEAVE:e.constructor.Event.FOCUSOUT;t(e.element).on(i,e.config.selector,function(t){return e._enter(t)}).on(s,e.config.selector,function(t){return e._leave(t)})}t(e.element).closest(".modal").on("hide.bs.modal",function(){return e.hide()})}),this.config.selector?this.config=r({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},I._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},I._enter=function(e,n){var i=this.constructor.DATA_KEY;(n=n||t(e.currentTarget).data(i))||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(i,n)),e&&(n._activeTrigger["focusin"===e.type?T:E]=!0),t(n.getTipElement()).hasClass(p)||n._hoverState===f?n._hoverState=f:(clearTimeout(n._timeout),n._hoverState=f,n.config.delay&&n.config.delay.show?n._timeout=setTimeout(function(){n._hoverState===f&&n.show()},n.config.delay.show):n.show())},I._leave=function(e,n){var i=this.constructor.DATA_KEY;(n=n||t(e.currentTarget).data(i))||(n=new this.constructor(e.currentTarget,this._getDelegateConfig()),t(e.currentTarget).data(i,n)),e&&(n._activeTrigger["focusout"===e.type?T:E]=!1),n._isWithActiveTrigger()||(clearTimeout(n._timeout),n._hoverState=d,n.config.delay&&n.config.delay.hide?n._timeout=setTimeout(function(){n._hoverState===d&&n.hide()},n.config.delay.hide):n.hide())},I._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},I._getConfig=function(n){return"number"==typeof(n=r({},this.constructor.Default,t(this.element).data(),n)).delay&&(n.delay={show:n.delay,hide:n.delay}),"number"==typeof n.title&&(n.title=n.title.toString()),"number"==typeof n.content&&(n.content=n.content.toString()),P.typeCheckConfig(e,n,this.constructor.DefaultType),n},I._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},I._cleanTipClass=function(){var e=t(this.getTipElement()),n=e.attr("class").match(l);null!==n&&n.length>0&&e.removeClass(n.join(""))},I._handlePopperPlacementChange=function(t){this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},I._fixTransition=function(){var e=this.getTipElement(),n=this.config.animation;null===e.getAttribute("x-placement")&&(t(e).removeClass(g),this.config.animation=!1,this.hide(),this.show(),this.config.animation=n)},a._jQueryInterface=function(e){return this.each(function(){var n=t(this).data(i),s="object"==typeof e&&e;if((n||!/dispose|hide/.test(e))&&(n||(n=new a(this,s),t(this).data(i,n)),"string"==typeof e)){if("undefined"==typeof n[e])throw new TypeError('No method named "'+e+'"');n[e]()}})},s(a,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return u}},{key:"NAME",get:function(){return e}},{key:"DATA_KEY",get:function(){return i}},{key:"Event",get:function(){return _}},{key:"EVENT_KEY",get:function(){return o}},{key:"DefaultType",get:function(){return h}}]),a}();return t.fn[e]=I._jQueryInterface,t.fn[e].Constructor=I,t.fn[e].noConflict=function(){return t.fn[e]=a,I._jQueryInterface},I}(e),x=function(t){var e="popover",n="bs.popover",i="."+n,o=t.fn[e],a=new RegExp("(^|\\s)bs-popover\\S+","g"),l=r({},U.Default,{placement:"right",trigger:"click",content:"",template:''}),h=r({},U.DefaultType,{content:"(string|element|function)"}),c="fade",u="show",f=".popover-header",d=".popover-body",_={HIDE:"hide"+i,HIDDEN:"hidden"+i,SHOW:"show"+i,SHOWN:"shown"+i,INSERTED:"inserted"+i,CLICK:"click"+i,FOCUSIN:"focusin"+i,FOCUSOUT:"focusout"+i,MOUSEENTER:"mouseenter"+i,MOUSELEAVE:"mouseleave"+i},g=function(r){var o,g;function p(){return r.apply(this,arguments)||this}g=r,(o=p).prototype=Object.create(g.prototype),o.prototype.constructor=o,o.__proto__=g;var m=p.prototype;return m.isWithContent=function(){return this.getTitle()||this._getContent()},m.addAttachmentClass=function(e){t(this.getTipElement()).addClass("bs-popover-"+e)},m.getTipElement=function(){return this.tip=this.tip||t(this.config.template)[0],this.tip},m.setContent=function(){var e=t(this.getTipElement());this.setElementContent(e.find(f),this.getTitle());var n=this._getContent();"function"==typeof n&&(n=n.call(this.element)),this.setElementContent(e.find(d),n),e.removeClass(c+" "+u)},m._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},m._cleanTipClass=function(){var e=t(this.getTipElement()),n=e.attr("class").match(a);null!==n&&n.length>0&&e.removeClass(n.join(""))},p._jQueryInterface=function(e){return this.each(function(){var i=t(this).data(n),s="object"==typeof e?e:null;if((i||!/destroy|hide/.test(e))&&(i||(i=new p(this,s),t(this).data(n,i)),"string"==typeof e)){if("undefined"==typeof i[e])throw new TypeError('No method named "'+e+'"');i[e]()}})},s(p,null,[{key:"VERSION",get:function(){return"4.0.0"}},{key:"Default",get:function(){return l}},{key:"NAME",get:function(){return e}},{key:"DATA_KEY",get:function(){return n}},{key:"Event",get:function(){return _}},{key:"EVENT_KEY",get:function(){return i}},{key:"DefaultType",get:function(){return h}}]),p}(U);return t.fn[e]=g._jQueryInterface,t.fn[e].Constructor=g,t.fn[e].noConflict=function(){return t.fn[e]=o,g._jQueryInterface},g}(e),K=function(t){var e="scrollspy",n="bs.scrollspy",i="."+n,o=t.fn[e],a={offset:10,method:"auto",target:""},l={offset:"number",method:"string",target:"(string|element)"},h={ACTIVATE:"activate"+i,SCROLL:"scroll"+i,LOAD_DATA_API:"load"+i+".data-api"},c="dropdown-item",u="active",f={DATA_SPY:'[data-spy="scroll"]',ACTIVE:".active",NAV_LIST_GROUP:".nav, .list-group",NAV_LINKS:".nav-link",NAV_ITEMS:".nav-item",LIST_ITEMS:".list-group-item",DROPDOWN:".dropdown",DROPDOWN_ITEMS:".dropdown-item",DROPDOWN_TOGGLE:".dropdown-toggle"},d="offset",_="position",g=function(){function o(e,n){var i=this;this._element=e,this._scrollElement="BODY"===e.tagName?window:e,this._config=this._getConfig(n),this._selector=this._config.target+" "+f.NAV_LINKS+","+this._config.target+" "+f.LIST_ITEMS+","+this._config.target+" "+f.DROPDOWN_ITEMS,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,t(this._scrollElement).on(h.SCROLL,function(t){return i._process(t)}),this.refresh(),this._process()}var g=o.prototype;return g.refresh=function(){var e=this,n=this._scrollElement===this._scrollElement.window?d:_,i="auto"===this._config.method?n:this._config.method,s=i===_?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),t.makeArray(t(this._selector)).map(function(e){var n,r=P.getSelectorFromElement(e);if(r&&(n=t(r)[0]),n){var o=n.getBoundingClientRect();if(o.width||o.height)return[t(n)[i]().top+s,r]}return null}).filter(function(t){return t}).sort(function(t,e){return t[0]-e[0]}).forEach(function(t){e._offsets.push(t[0]),e._targets.push(t[1])})},g.dispose=function(){t.removeData(this._element,n),t(this._scrollElement).off(i),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},g._getConfig=function(n){if("string"!=typeof(n=r({},a,n)).target){var i=t(n.target).attr("id");i||(i=P.getUID(e),t(n.target).attr("id",i)),n.target="#"+i}return P.typeCheckConfig(e,n,l),n},g._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},g._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},g._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},g._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(var s=this._offsets.length;s--;){this._activeTarget!==this._targets[s]&&t>=this._offsets[s]&&("undefined"==typeof this._offsets[s+1]||t=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}(e),t.Util=P,t.Alert=L,t.Button=R,t.Carousel=j,t.Collapse=H,t.Dropdown=W,t.Modal=M,t.Popover=x,t.Scrollspy=K,t.Tab=V,t.Tooltip=U,Object.defineProperty(t,"__esModule",{value:!0})}); 7 | //# sourceMappingURL=bootstrap.min.js.map -------------------------------------------------------------------------------- /reactjs/public/js/dataTables.bootstrap4.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | DataTables Bootstrap 4 integration 3 | ©2011-2017 SpryMedia Ltd - datatables.net/license 4 | */ 5 | (function(b){"function"===typeof define&&define.amd?define(["jquery","datatables.net"],function(a){return b(a,window,document)}):"object"===typeof exports?module.exports=function(a,d){a||(a=window);if(!d||!d.fn.dataTable)d=require("datatables.net")(a,d).$;return b(d,a,a.document)}:b(jQuery,window,document)})(function(b,a,d,m){var f=b.fn.dataTable;b.extend(!0,f.defaults,{dom:"<'row'<'col-sm-12 col-md-6'l><'col-sm-12 col-md-6'f>><'row'<'col-sm-12'tr>><'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", 6 | renderer:"bootstrap"});b.extend(f.ext.classes,{sWrapper:"dataTables_wrapper dt-bootstrap4",sFilterInput:"form-control form-control-sm",sLengthSelect:"custom-select custom-select-sm form-control form-control-sm",sProcessing:"dataTables_processing card",sPageButton:"paginate_button page-item"});f.ext.renderer.pageButton.bootstrap=function(a,h,r,s,j,n){var o=new f.Api(a),t=a.oClasses,k=a.oLanguage.oPaginate,u=a.oLanguage.oAria.paginate||{},e,g,p=0,q=function(d,f){var l,h,i,c,m=function(a){a.preventDefault(); 7 | !b(a.currentTarget).hasClass("disabled")&&o.page()!=a.data.action&&o.page(a.data.action).draw("page")};l=0;for(h=f.length;l", 8 | {"class":t.sPageButton+" "+g,id:0===r&&"string"===typeof c?a.sTableId+"_"+c:null}).append(b("",{href:"#","aria-controls":a.sTableId,"aria-label":u[c],"data-dt-idx":p,tabindex:a.iTabIndex,"class":"page-link"}).html(e)).appendTo(d),a.oApi._fnBindAction(i,{action:c},m),p++)}},i;try{i=b(h).find(d.activeElement).data("dt-idx")}catch(v){}q(b(h).empty().html('