├── LICENSE ├── MockSchema └── index.js ├── QueryTest └── query.js ├── README.md ├── README_assets ├── halfcat.jpeg ├── popup_cache.png ├── popup_filled.png ├── popup_prefill.png └── querymockimage.jpeg ├── mockData ├── attachButtonListener.js ├── convertGqlargToObject.js ├── createPopUpWindow.js ├── dataFiles.js ├── determineArguements.js ├── findQueryName.js ├── findQueryObject.js ├── insertEntriesIntoObject.js ├── mockQuery.js ├── saveCacheToSessionStorage.js ├── updateCacheFromSessionStorage.js ├── updateCacheWithUserInput.js └── updateObjWithCache.js └── package.json /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 OSLabs Beta 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MockSchema/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Mock-Schema 5 | * Create mock schema based off of desired query for Apollo GraphQL 6 | * 7 | * @author Apollo's Library 8 | */ 9 | 10 | // require readline to connect with the terminal 11 | const readline = require('readline'); 12 | // require boxen, chalk for styling purposes 13 | const boxen = require('boxen'); 14 | const chalk = require('chalk'); 15 | // require fs in order to createReadStream, appendFile, and readFileSync to find file where query is 16 | const { createReadStream, appendFile, readFileSync } = require('fs'); 17 | 18 | // createInterface for readline to accept prompts from keyboard 19 | const rl = readline.createInterface({ 20 | input: process.stdin, 21 | output: process.stdout 22 | }) 23 | 24 | // styling for boxen 25 | const boxenOptions = { 26 | padding: 5, 27 | margin: 5, 28 | borderStyle: 'double', 29 | borderColor: 'magenta', 30 | backgroundColor: 'magenta', 31 | }; 32 | 33 | function strToSchema(str) { 34 | // declare empty arr to store brackets 35 | let arr = []; 36 | let type; 37 | let typearr = []; 38 | let cache = {}; 39 | for (let i = 0; i < str.length; i++) { 40 | if (str[i] === '{') { 41 | // making sure not the first bracket 42 | if (arr.length) { 43 | let spc = []; 44 | for (let j = i; j > 0; j--) { 45 | // declare another arr for whitespace 46 | if (str[j] === ' ') { 47 | if (spc.length) { 48 | type = str.slice(j + 1, i - 1); 49 | 50 | if (cache[type]) { 51 | continue; 52 | } 53 | // console.log(type); 54 | else { 55 | typearr.push(type); 56 | cache[type] = true; 57 | break; 58 | } 59 | 60 | // console.log(typearr); 61 | } 62 | spc.push(str[j]); 63 | } 64 | } 65 | } 66 | arr.push(str[i]); 67 | } 68 | } 69 | return typearr; 70 | }; 71 | 72 | function strToArgs(str) { 73 | // declare empty arr to store brackets 74 | let arr = []; 75 | let prop; 76 | let cache = {}; 77 | let result = []; 78 | let dig = 0; 79 | for (let i = 0 ; i < str.length; i++) { 80 | if (str[i] === '{' && cache[dig-1]) { 81 | cache[dig] = str.indexOf('{', cache[dig-1] + 1); 82 | dig++; 83 | } 84 | 85 | if (str[i] === '{' && !cache[dig - 1]) { 86 | cache[dig] = str.indexOf('{'); 87 | dig++; 88 | } 89 | if (str[i] === '}') { 90 | // console.log(dig) 91 | cache[dig] = str.indexOf('}'); 92 | } 93 | } 94 | // console.log(cache); 95 | // console.log(str[104]) 96 | let count = 0; 97 | for (let i = 0; i < str.length; i++) { 98 | let typearr = []; 99 | let index; 100 | if (count.toString() === Object.keys(cache).pop()) { 101 | let stg = []; 102 | let init; 103 | for (let i = cache[count-1]; i < cache[count]; i++) { 104 | if (str[i] === ' ' && stg.length < (count)*2) { 105 | stg.push(str[i]); 106 | continue; 107 | }; 108 | if (stg.length === count * 2 && str[i-1] === ' ') { 109 | init = i; 110 | // console.log(init); 111 | } 112 | if (str[i] === ' ' && str[i-1] !== ' ') { 113 | // console.log(init) 114 | // console.log(i); 115 | prop = str.slice(init, i-1); 116 | // console.log(prop); 117 | typearr.push(prop); 118 | spc = []; 119 | spc.push(str[i]); 120 | } 121 | } 122 | break; 123 | } 124 | if (str[i] === '{') { 125 | index = str.indexOf(str[i], count); 126 | count++; 127 | // making sure not the first bracket 128 | if (arr.length) { 129 | let spc = []; 130 | let beg; 131 | for (let j = i; j < cache[count]; j++) { 132 | if (str[j] === ' ' && spc.length < count * 2) { 133 | spc.push(str[j]); 134 | continue; 135 | }; 136 | if (spc.length === count * 2 && str[j-1] === ' ') { 137 | beg = j; 138 | // console.log(beg) 139 | } 140 | if (str[j] === ' ' && str[j+1] === '{') { 141 | prop = str.slice(beg, j); 142 | typearr.push(prop); 143 | spc =[]; 144 | spc.push(str[j]) 145 | // console.log(prop); 146 | } 147 | if (str[j] === ' ' && str[j+1] !== '{') { 148 | // console.log(beg) 149 | // console.log(j); 150 | prop = str.slice(beg, j-1); 151 | // console.log(prop); 152 | typearr.push(prop); 153 | spc = []; 154 | spc.push(str[j]); 155 | } 156 | } 157 | // console.log(typearr) 158 | result.push(typearr); 159 | } 160 | arr.push(str[i]); 161 | } 162 | } 163 | return result; 164 | }; 165 | 166 | function createType(arr, arr1) { 167 | let result = []; 168 | for (let i = 0; i < arr.length; i++) { 169 | let gql = `type ${arr[i]} { 170 | ` 171 | for (let j = 0; j < arr1[i].length; j++) { 172 | let add; 173 | if (j === arr1[i].length - 1) { 174 | add = `${arr1[i][j]}: String! 175 | `; 176 | // console.log(add); 177 | gql = gql.concat(add); 178 | continue; 179 | } 180 | add = `${arr1[i][j]}: String! 181 | ` 182 | // console.log(add); 183 | gql = gql.concat(add); 184 | } 185 | gql = gql.concat(`}`); 186 | result.push(gql); 187 | } 188 | return result; 189 | } 190 | 191 | const findAndShowQuery = () => { 192 | // regex to find queries from given file 193 | const regex = /\`([^\`]*)\`/gm; 194 | let foundQuery; 195 | let newSchema; 196 | // prompt user to enter path where query(s) are stored 197 | rl.question('Where is your query stored ? ', function(data){ 198 | // initialize constant with value taken from createReadStream 199 | const queryData = createReadStream(data); 200 | // once the data is collected from the createReadStream parse the information 201 | queryData.on('data', chunk => { 202 | let body = []; 203 | body.push(chunk); 204 | // buffer the information into a readable string instead of bytes 205 | let buffer = Buffer.concat(body).toString(); 206 | // parse the query from the string with the regular expression 207 | foundQuery = buffer.match(regex); 208 | foundQuery.forEach((el) => { 209 | // invoke strToSchema to parse type 210 | const schemaType = strToSchema(el); 211 | // invoke strToArgs to parse properties 212 | const schemaProperty = strToArgs(el); 213 | // invoke createType to get individual parts of the schemas 214 | const finalSchema = createType(schemaType, schemaProperty); 215 | // iterate thru finalSchema to produce one cohesive string 216 | function finalSchemaStr (arr) { 217 | let bigstr = ''; 218 | for (let i = 0; i < finalSchema.length; i++) { 219 | bigstr = bigstr.concat(finalSchema[i] + `\n\n`); 220 | } 221 | return bigstr; 222 | } 223 | // prompt user for the path where they want their schema stored 224 | rl.question('Please declare the path where you would like your schema stored : ', function(storedSchema){ 225 | newSchema = storedSchema; 226 | const schemaStr = finalSchemaStr(finalSchema); 227 | // create or append to file received from user input 228 | appendFile(newSchema, schemaStr, (err) => { 229 | if (err) { 230 | console.log(err); 231 | } else { 232 | console.log('file appended'); 233 | } 234 | // close readline instance 235 | rl.close(); 236 | }) 237 | }) 238 | }) 239 | }) 240 | }) 241 | // on close confirm the final mock schema with in the console 242 | rl.on('close', function() { 243 | const answer = boxen(chalk.italic.bold(`This is your schema file, \n ${readFileSync(newSchema)}`), boxenOptions); 244 | console.log(answer); 245 | process.exit(0); 246 | }) 247 | } 248 | 249 | // invoke the query when the command is ran in the terminal 250 | findAndShowQuery(); 251 | -------------------------------------------------------------------------------- /QueryTest/query.js: -------------------------------------------------------------------------------- 1 | const { gql } = require('apollo-graphql'); 2 | 3 | const dndChar = gql ` 4 | query class { 5 | class { 6 | name 7 | hit_die 8 | spellcasting { 9 | spellcasting_ability { 10 | name 11 | } 12 | } 13 | } 14 | } 15 | ` 16 | 17 | module.exports = dndChar; 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | Logo for QueryMock 3 | 4 |

The QueryMock library is built for developers who are using Apollo, GraphQL, and React.

5 |

We currently have two books in our library:

6 | 1) mockQuery -> Which is a function that provides mock data for front end developers when the backend is not set up. 7 |
8 |
9 | 2) create-schema -> Which is a command line tool that will generate a mock schema using a provided query. NOTE: create-schema requires Apollo GraphQL to be installed. 10 |
11 |
12 |
13 |

INSTALLATION

14 |

Downloading The Package

15 |

To begin, fork this repo and then use the following code where you can access it in your project's file. 16 |
17 |
18 | $ git clone https://github.com/oslabs-beta/apollos_library.git 19 | ​
20 |
21 |

It has some dependencies, so be sure to go to the file and enter: 22 | ​
23 |
24 | $ npm install 25 | ​
26 |
27 | Following that, enter: 28 | ​

29 | $ npm install -g 30 | ​
31 |
32 | WARNING: Do not add the global flag during the inital npm install, this will cause an error when attempting to use create-schema.

33 |
34 |
35 |

USING QueryMock

36 | ​ 37 |

TOOL #1: The mockQuery() Method

38 |

DESCRIPTION:

mockQuery is a temporary useQuery replacement, that provides mock data for front end development especially when the backend and/or schema have not been created. The mockQuery method will provide you data so that you can visualize your front end code. 39 | ​ 40 | The idea is that while the backend is under construction, you would replace useQuery with mockQuery(), so that when your database is set up, you can swap them back and already know how everything will render on the page.

41 | ​ 42 |

Importing The Method

43 | In every page that you are running a GraphQL search and using the useQuery method, import QueryMock at the top of the page

44 | ​ 45 | import al from '[your file path]/Query_Mock 46 |
​ 47 |

Implementing the Method

48 |

Wherever you are using the useQuery method, replace it like we do in the following code: 49 | ​
50 |
51 | original code 52 |
53 |
54 | 55 | const { data } = useQuery(gqlSearch)
56 | ... do something with your data 57 |
58 |
59 |
60 | replaced code 61 |

62 | 63 | const { data } = al.mockQuery(gqlSearch, Arg2, Arg3, Arg4)
64 | ... do something with your data 65 |
66 |
67 |
68 |

If you have a query that uses variables, then you would do the following to your code 69 |
70 | original code: 71 |

72 | 73 | const { loading, error, data } = useQuery(GET_TRACK, {variables: { variableGoesHere }}, [optional additional arguements here]) 74 |
...do something with your data 75 |
76 |
77 |
78 | replaced code:
79 | 80 | const { loading, error, data } = al.mockQuery(GET_TRACK, {variables: { trackId }}) 81 | ...do something with your data 82 | 83 |
84 | ​ 85 |

The Parameters: mockQuery(gql, obj, num, string)

86 | ​ 87 | 1) The first paremeter must be a gql search, the same type of search used for Apollo's useQuery method. Here is link to the documentation for how those queries are constructed (https://www.apollographql.com/docs/react/data/queries/); 88 | ​
89 |
90 | Entering only 1 parameter will return mock/dummy data in string format. If you're looking for different data types then see the functionality from the flag parameter. 91 | ​​
92 |
93 | *The remaining arguments are optional and can be entered in any order or left out.* 94 | ​

95 | 2) Enter an integer for the number of times you want your data duplicated. You will receive an array with 1 object if you don't specifiy. *please note that if you enter 1 or 0 then your data will return to you as an object. If you enter anything greater than 1, your data will be returned to you as objects in an array. 96 | ​

97 | 3) The object is for variables that you want to pass into your GraphQL query. See this link for more info on using it with useQuery: https://www.apollographql.com/docs/react/data/queries/#caching-query-results. 98 | ​

99 | 4) The flag can be either: 100 | - 'error' - This will return an error so that you can test how your site will render with an error. 101 | 102 | - 'loading' - This will return 'loading' so that you can test how your site will render while loading. 103 | 104 | - 'insert' - (for personalization) A pop up window will appear with input boxes so that you can either enter the exact data you want to be displayed or you can choose a data type by placing a tilsde in front of specific words. 105 |
106 |
107 | Using the "insert" flag will cause a popup window to appear where you can personalize the data. If you don't want to come up with your own data, then we supply some key words that you can use in order to populate your page with specific data:
108 |
109 | drawing of Puery the Cat 110 | Data Type Key Words: 111 | - to enter an int type: 112 | - ~int 113 | 114 | - To enter a float type: 115 | - ~float 116 | 117 | - To enter a block of text then enter the ~text followed by how many characters you want. The following example will return text with 15 characters, 75 characters, and 345 characters 118 | - ~text15 119 | - ~text75 120 | - ~text345 121 | ​ 122 | - To enter an address type: 123 | - ~address 124 | ​ 125 | - To enter a phone number type: 126 | - ~phone 127 | ​ 128 | - To enter a photo url then type: 129 | - ~photo 130 | ​ 131 |
132 |
133 |

Session Storage

134 | The data will stay in your session storage until you close the browser. Once you have your mock data set, then you can remove the flag argument and keep working on your page with the mock data provided. 135 |
136 |
137 |
138 |

TOOL #2: create-schema CLI

139 | 140 |

DESCRIPTION:

create-schema is a command line based tool that provides a mock schema based off of a provided query, making it extremely easy to start using GraphQL with very little setup.

141 |
142 |

How to use create-schema

143 | Currently, in order to use create-schema, you must have a file that only contains one gql query. We're currently working on adding suport for multiple queries! 144 | ​
145 |
146 |

Example Query File:

147 |
148 | 149 | const { gql } = require('apollo-graphql'); 150 |
151 |
152 | const dndChar = gql` 153 | ​
154 | query class { 155 | ​
156 | __class { 157 | ​
158 | ____name 159 | ​
160 | ____hit_die 161 | ​
162 | ____spellcasting { 163 | ​
164 | ______spellcasting_ability { 165 | ​
166 | ________name 167 | ​
168 | ______} 169 | ​
170 | ____} 171 | ​
172 | __} 173 | ​
174 | } 175 | ​
176 | `; 177 |
178 |
179 | 180 | ​ 181 | NOTE: _ is acting as a stand in for a space in the above example. 182 |
183 |
184 | ​ 185 | ​ 186 | After the file is created, the only information you need, to start using create-schema is the relative path of your file. 187 |
188 |
189 |

Implementing the Method

190 |
191 | ​ 192 | Once you have that information, type the following command into your terminal: 193 | ​
194 |
195 | create-schema 196 | ​
197 |
198 | After the command is run, follow the provided prompts to create your mock schema! 199 |
200 | ​ 201 |

Example:

202 |
203 | create-schema 204 | ​
205 |
206 | -> 207 |
208 | ​
209 | Where is your query stored? -> ./yourDir/yourQueryFile 210 | ​
211 |
212 | -> 213 |
214 | ​
215 | Please declare the path where you would like your schema stored: -> ./yourDir/yourSchemaFile 216 | ​
217 |
218 | NOTE: If the provided path leads to a file that doesn't exist, the file will be created for you. If the path leads to a file that already exists, the mock schema will be placed under any data already present in the file. 219 | ​
220 |
221 | After all prompts have been followed, the created mock schema will be displayed in the terminal. Currently, the default value is a string. We're working on adding support for more types, but at the moment any value other than a string will have to be manually added after the creation of the mock schema. 222 | ​ 223 |
224 |
225 |
226 |

Next Steps:

227 | We are hoping to deploy our product on npmjs as an installable package in the near future. This is our immediate next step. After that we want to ensure that we can implement the ability to return an array of objects that are deeply nested in a given query in regards to our first feature. For our second feature we are hoping to integrate more prompts for the user to dictate other data types they want to populate in their mock schema. Currently, it can only populate strings and it needs to be manually updated in the new file to account for any other possible data types. 228 |
229 |
230 | We are also interested in working on a third feature that 231 | addresses the issue of query handling in the Gateway with Apollo Federation. This isn't a fully-fleshed out idea, currently, however from what we could deduce there were some issues in regard to how node queries were specifically being handled by the Gateway when working with React Relay. 232 | 233 | 234 | 235 |
236 |
237 |

Meet The Team

238 | QueryMock is currently a team of four software engineers, excited about the possibilities of Apollo GraphQL. Here is our team: 239 |
240 |
241 | Jacob Jurado: 242 |
243 | - github: https://github.com/jakejurado 244 |
245 | - linkedin: https://www.linkedin.com/in/jacob-jurado/ 246 |
247 |
248 | Autumn Wallen: 249 |
250 | - github: https://github.com/Autumn-Wallen 251 |
252 | - linkedin: https://www.linkedin.com/in/autumn-wallen/ 253 |
254 |
255 | Ziquan “ZQ” Deng: 256 |
257 | - github: https://github.com/ZQland 258 |
259 | - linkedin: https://www.linkedin.com/in/ziquan-deng/ 260 |
261 |
262 | Jamie Clignett: 263 |
264 | - github: https://github.com/jamie-clignett 265 |
266 | - linkedin: https://www.linkedin.com/in/jamie-clignett/ 267 | 268 | 269 |
270 |
271 | Thank you! 272 |
273 | We appreciate you taking the time to read our article. If you find this product useful or if you are curious to know more, feel free to visit our github repository, and our splash page! Soon we will be launching this on npmjs, so that you can directly install our package from there. 274 |
275 |
276 | Special thanks to Katherine Kim for mentoring and giving us guidance. 277 |
278 |
279 | We would also like to thank Natalie Klein, Mike Masatsugu and Alexander Holden for supporting us in our creation of Query Mock. 280 | 281 | 282 | drawing of Puery the Cat 283 | -------------------------------------------------------------------------------- /README_assets/halfcat.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/QueryMock/f4bfbba9a1db5467b4f0a5a47589aeb10eeb57c0/README_assets/halfcat.jpeg -------------------------------------------------------------------------------- /README_assets/popup_cache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/QueryMock/f4bfbba9a1db5467b4f0a5a47589aeb10eeb57c0/README_assets/popup_cache.png -------------------------------------------------------------------------------- /README_assets/popup_filled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/QueryMock/f4bfbba9a1db5467b4f0a5a47589aeb10eeb57c0/README_assets/popup_filled.png -------------------------------------------------------------------------------- /README_assets/popup_prefill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/QueryMock/f4bfbba9a1db5467b4f0a5a47589aeb10eeb57c0/README_assets/popup_prefill.png -------------------------------------------------------------------------------- /README_assets/querymockimage.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oslabs-beta/QueryMock/f4bfbba9a1db5467b4f0a5a47589aeb10eeb57c0/README_assets/querymockimage.jpeg -------------------------------------------------------------------------------- /mockData/attachButtonListener.js: -------------------------------------------------------------------------------- 1 | import dataFiles from './dataFiles'; 2 | import updateCacheWithUserInputs from './updateCacheWithUserInput'; 3 | import saveCacheToSessionStorage from './saveCacheToSessionStorage'; 4 | import insertEntriesIntoObject from './insertEntriesIntoObject'; 5 | 6 | 7 | //INPUT -> setItem: React Hook 8 | //INPUT -> obj: Object 9 | //INPUT -> cache: Object 10 | //OUTPUT -> null 11 | //description: attaches a button listener to 'mockButton' div. When clicked the cache is updated with user inputs and saved for page reload, the inputed elements on the dom are saved to the object. Lastly we update state with the new object. 12 | function attachButtonListener(setItem, obj, cache, btnPrss){ 13 | document.getElementById('mockButton').onclick = function(e){ 14 | updateCacheWithUserInputs(cache, dataFiles); 15 | insertEntriesIntoObject(obj, cache) 16 | saveCacheToSessionStorage(cache); 17 | btnPrss = true; 18 | 19 | document.getElementById('mockPop').remove(); 20 | setItem(obj); 21 | } 22 | } 23 | 24 | 25 | export default attachButtonListener; -------------------------------------------------------------------------------- /mockData/convertGqlargToObject.js: -------------------------------------------------------------------------------- 1 | //INPUT -> input: gql search for useQuery hook 2 | //INPUT -> num: Number; 3 | //description: accepts a useQuery search and returns an object and mock data for that request. If num is greater than 1, it will return it in an array inside data.[query search name]; otherwise it will return as a single object 4 | function convertGqlargToObject(input, num, arg){ 5 | // finding the array of objects with all the Graph QL query 6 | const arr = input.definitions[0].selectionSet.selections[0].selectionSet.selections; 7 | // declaring a empty object to use later 8 | const cache = {}; 9 | function loopSelection (arr) { 10 | // another function to loop thru the array and populate cache 11 | 12 | for (let i = 0; i < arr.length; i++) { 13 | function nestedLoop (arr, arr1, i) { 14 | for (let j = 0; j < arr1.length; j++) { 15 | let val = arr1[j].name.value; 16 | cache[arr[i].name.value][val] = `${arr1[j].name.value}_01`; 17 | 18 | } 19 | return cache; 20 | } 21 | // if one of the object has a selectionSet which means it has its own properties, then recursively invoke loopSelection 22 | if (arr[i].selectionSet) { 23 | cache[arr[i].name.value] = {}; 24 | nestedLoop(arr, arr[i].selectionSet.selections, i); 25 | } 26 | else cache[arr[i].name.value] = `${arr[i].name.value}_01`; 27 | } 28 | return cache; 29 | } 30 | loopSelection(arr); 31 | const key = input.definitions[0].selectionSet.selections[0].name.value; 32 | if (num === 1 || num === 0) { 33 | const ncache = { 34 | data: { 35 | [key]: cache 36 | } 37 | } 38 | return ncache; 39 | } 40 | if (num > 1) { 41 | let narr = []; 42 | for (let i = 0; i < num; i++) { 43 | narr.push(cache); 44 | } 45 | const ncache = { data: 46 | { 47 | [key]: narr 48 | } 49 | } 50 | return ncache; 51 | } 52 | } 53 | 54 | export default convertGqlargToObject; -------------------------------------------------------------------------------- /mockData/createPopUpWindow.js: -------------------------------------------------------------------------------- 1 | import findQueryObject from './findQueryObject'; 2 | 3 | 4 | 5 | //INPUT -> obj: Object 6 | //INPUT -> cache: Object 7 | //Description: recieves object -> populates popup with object key/value pairs of Object unless Cache has a different value for the same key 8 | 9 | function createPopUpWindow(obj, cache){ 10 | 11 | //Creating the dom elements and styling it. 12 | const body = document.getElementsByTagName('body')[0]; 13 | const mockPop = document.createElement('div'); 14 | mockPop.id = 'mockPop'; 15 | mockPop.setAttribute("style", "width: 100%; height: 100%; position: fixed; top: 0px; left: 0px; background-color: rgba(248, 220, 242); display: grid; grid-template-rows: 2% 1fr 2%;") 16 | 17 | //Creating the elements within the dom. 18 | const popUp = document.createElement('div'); 19 | popUp.id = 'popUp'; 20 | popUp.setAttribute("style", "background-color: white; width: 60%; max-width: 650px; margin: 1% auto 0 auto; border: solid; border-color: black; border-radius: 5%; border-width: thin; box-shadow: 10px 10px 25px rgb(216, 211, 211); min-width: 600px; grid-row: 2; overflow: scroll;"); 21 | mockPop.appendChild(popUp); 22 | 23 | //add image for popup 24 | const img = document.createElement('img'); 25 | img.setAttribute('src', 'https://lh3.googleusercontent.com/pw/AL9nZEUQDLLDUjHxpJBZ9HWnZ9X_oMCCj59rMUgvSwFmGOkwAfpBw0TZOIKUfA9_E7Q8j82aXA4e0ncrP8SNgtg6CMQY96eGOey6VhF8DxCH5yFajSKL99wmIVZ6FgOwei2C9YYIWE2OUp9yw5sA4QVPkHIn=w1840-h674-no?authuser=0'); 26 | img.setAttribute('style', "width: 100%; max-width: 550px padding: 5% 10% 0 10%;"); 27 | popUp.appendChild(img); 28 | 29 | //Create description paragraph 30 | const p = document.createElement('p'); 31 | p.innerHTML = "Hi! Thanks for using Apollo's Library mockQuery!
We have prefilled the mock data fields with text.
Replace any of the prefilled input boxes with your personalized mock data
and then click submit.

You can re-run the mockQuery function without the 'P' tag
and your information will be retained.
If you have any questions, please check out our docs. Query on!" 32 | p.setAttribute('style', "padding-left: 10%; padding-right: 10%; text-align: center; font-size: 1em; color:rgb(49, 49, 49);") 33 | popUp.appendChild(p); 34 | 35 | //Create ul 36 | const ul = document.createElement('ul'); 37 | ul.id = 'mockList'; 38 | ul.setAttribute('style', "list-style-type: none; margin: 0; padding: 4% 10% 1% 10%; font-size: 1.25em;"); 39 | popUp.appendChild(ul); 40 | 41 | //grabing the object within the query search. checks if it is in an array. 42 | let queryObject = findQueryObject(obj); 43 | 44 | 45 | //adding an
  • to the dom with each key/value from the object 46 | function addElementToDom(key, value, prepend = ''){ 47 | let li = document.createElement('li'); 48 | li.id = `ul_${key}` 49 | li.setAttribute('style', 'width: 100%; display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; margin-bottom: 2%;'); 50 | 51 | const mockDiv = document.createElement('div'); 52 | mockDiv.id = 'mockDiv' 53 | mockDiv.innerText = `${prepend} ${key}: `; 54 | mockDiv.setAttribute('style', "grid-column: 1 / 2; text-align: right; padding-right: 5%; color: rgb(65, 28, 65); text-shadow: 2px 2px 3px rgb(156, 156, 156);") 55 | li.appendChild(mockDiv); 56 | 57 | const mockInput = document.createElement('input'); 58 | mockInput.setAttribute('style', 'grid-column: 2 / 5; width: 96%; margin-left: 1%; border-radius: 5px; margin-top: -5px; line-height: 2em; border-color:rgb(65, 28, 65); box-shadow: 2px 2px 5px rgb(156, 156, 156);') 59 | mockInput.id = key; 60 | mockInput.setAttribute('placeholder', `${value}`); 61 | li.appendChild(mockInput); 62 | 63 | ul.appendChild(li); 64 | } 65 | 66 | //adding the key/value from the object to the local cache 67 | function addElementToLocalCache(key, value, cache){ 68 | cache[key] = value; 69 | } 70 | 71 | /** 72 | * FUNCTION: iterateObj(obj, callback, prepend); 73 | * @param {} obj -> the object with just the query fields 74 | * @param {*} callback -> callback runs for each element in the field 75 | * @param {*} prepend --> keeps track of what object we are in for nested objects 76 | * Description: recurssively iterates over object key/values, runs callback on each pair, 77 | */ 78 | //iterating over input object to populate popup fields. 79 | function iterateObj(obj, callback, prepend = ''){ 80 | for(const [key, value] of Object.entries(obj)){ 81 | if(typeof value === 'string' || typeof value === 'number') { //checks if it's a nested object. 82 | if(key[0] !== '_' && key[1] !== '_'){ 83 | if(cache[key]){ 84 | callback(key, cache[key], prepend) 85 | // addElementToLocalCache(key, value, cache); 86 | } else{ 87 | callback(key, value, prepend) 88 | // addElementToLocalCache(key, value, cache); 89 | } 90 | } 91 | } else{ 92 | const prependText = prepend + key; 93 | iterateObj(value, callback, prependText) 94 | } 95 | } 96 | } 97 | iterateObj(queryObject, addElementToDom); 98 | 99 | //adding a submit Button 100 | const addHover = document.createElement('style'); 101 | addHover.appendChild(document.createTextNode("#mockButtonDiv:hover{box-shadow: 2px 2px 5px rgb(156, 156, 156);}")); 102 | addHover.appendChild(document.createTextNode("#mockButton:hover{color: white; backgroundColor: rgb(65, 28, 65); background-color: rgb(65, 28, 65);}")); 103 | document.querySelector('head').appendChild(addHover); 104 | 105 | 106 | const buttonDiv = document.createElement('div'); 107 | buttonDiv.id = "mockButtonDiv" 108 | buttonDiv.setAttribute('style', "margin: 5% auto 5% auto; width: 12%;") 109 | popUp.appendChild(buttonDiv); 110 | 111 | const button = document.createElement('button'); 112 | button.id = 'mockButton' 113 | button.innerText = 'submit'; 114 | button.setAttribute('style', "width: 100%; text-align: center; padding-top: 8%; padding-bottom: 8%; box-shadow: 2px 2px 5px rgb(156, 156, 156); border-color: rgb(65, 28, 65); border-width: thin; border-radius: 5px; background-color: rgba(248, 220, 242)") 115 | buttonDiv.appendChild(button); 116 | 117 | //adding all created elments to the page 118 | 119 | body.appendChild(mockPop); 120 | 121 | //adding the onlick function to the button 122 | // button.onclick = function(e){ 123 | 124 | // apollos_library.closePopUpWindow(obj); 125 | 126 | 127 | // } 128 | 129 | return; 130 | }; 131 | 132 | 133 | 134 | 135 | export default createPopUpWindow; -------------------------------------------------------------------------------- /mockData/dataFiles.js: -------------------------------------------------------------------------------- 1 | //TYPE: Object 2 | //description: This is used to convert inputs that are prepended with "~" to a data type or specific data. 3 | const dataFiles = { 4 | int: 127, 5 | float: parseFloat(127.27).toFixed(2), 6 | boolean: true, 7 | photo: { 8 | item: ['https://upload.wikimedia.org/wikipedia/commons/3/36/Vassily_Kandinsky%2C_1912_-_Improvisation_27%2C_Garden_of_Love_II.jpg', 'https://upload.wikimedia.org/wikipedia/commons/6/63/Robert_Delaunay%2C_1913%2C_Premier_Disque%2C_134_cm%2C_52.7_inches%2C_Private_collection.jpg', 'https://upload.wikimedia.org/wikipedia/en/2/2f/Franti%C5%A1ek_Kupka%2C_1912%2C_Amorpha%2C_fugue_en_deux_couleurs_%28Fugue_in_Two_Colors%29%2C_210_x_200_cm%2C_Narodni_Galerie%2C_Prague.jpg', 'https://upload.wikimedia.org/wikipedia/commons/f/fc/DasUndbild.jpg', 'https://upload.wikimedia.org/wikipedia/commons/1/15/Carlsund_Rapid_%281930%29.jpg'], 9 | index: 0 10 | }, 11 | address: { 12 | item:['2300 Oracle Way Austin, TX 78741', '4348 Fountain Ave, Los Angeles, CA 90029', '1000 5th Ave, New York, NY 10028', '2800 E Observatory Rd, Los Angeles, CA 90027', '125 La Salle St, New York, NY 10027'], 13 | index: 0 14 | }, 15 | phone: { 16 | item: ['(737)867-1000', '(213) 473-0800', '202-456-1111', '+353 1 679 6644', '(310) 325-6767', '(212) 932-3500'], 17 | index: 0 18 | }, 19 | text: { 20 | item: [`One dollar and eighty-seven cents. That was all. And sixty cents of it 21 | was in pennies. Pennies saved one and two at a time by bulldozing the 22 | grocer and the vegetable man and the butcher until one’s cheeks burned 23 | with the silent imputation of parsimony that such close dealing 24 | implied. Three times Della counted it. One dollar and eighty-seven 25 | cents. And the next day would be Christmas. 26 | 27 | There was clearly nothing to do but flop down on the shabby little 28 | couch and howl. So Della did it. Which instigates the moral reflection 29 | that life is made up of sobs, sniffles, and smiles, with sniffles 30 | predominating. 31 | 32 | While the mistress of the home is gradually subsiding from the first 33 | stage to the second, take a look at the home. A furnished flat at $8 34 | per week. It did not exactly beggar description, but it certainly had 35 | that word on the lookout for the mendicancy squad. 36 | 37 | In the vestibule below was a letter-box into which no letter would go, 38 | and an electric button from which no mortal finger could coax a ring. 39 | Also appertaining thereunto was a card bearing the name “Mr. James 40 | Dillingham Young.” 41 | 42 | The “Dillingham” had been flung to the breeze during a former period of 43 | prosperity when its possessor was being paid $30 per week. Now, when 44 | the income was shrunk to $20, though, they were thinking seriously of 45 | contracting to a modest and unassuming D. But whenever Mr. James 46 | Dillingham Young came home and reached his flat above he was called 47 | “Jim” and greatly hugged by Mrs. James Dillingham Young, already 48 | introduced to you as Della. Which is all very good. 49 | 50 | Della finished her cry and attended to her cheeks with the powder rag. 51 | She stood by the window and looked out dully at a gray cat walking a 52 | gray fence in a gray backyard. Tomorrow would be Christmas Day, and she 53 | had only $1.87 with which to buy Jim a present. She had been saving 54 | every penny she could for months, with this result. Twenty dollars a 55 | week doesn’t go far. Expenses had been greater than she had calculated. 56 | They always are. Only $1.87 to buy a present for Jim. Her Jim. Many a 57 | happy hour she had spent planning for something nice for him. Something 58 | fine and rare and sterling—something just a little bit near to being 59 | worthy of the honor of being owned by Jim. 60 | 61 | There was a pier glass between the windows of the room. Perhaps you 62 | have seen a pier glass in an $8 flat. A very thin and very agile person 63 | may, by observing his reflection in a rapid sequence of longitudinal 64 | strips, obtain a fairly accurate conception of his looks. Della, being 65 | slender, had mastered the art. 66 | 67 | Suddenly she whirled from the window and stood before the glass. Her 68 | eyes were shining brilliantly, but her face had lost its color within 69 | twenty seconds. Rapidly she pulled down her hair and let it fall to its 70 | full length. 71 | 72 | Now, there were two possessions of the James Dillingham Youngs in which 73 | they both took a mighty pride. One was Jim’s gold watch that had been 74 | his father’s and his grandfather’s. The other was Della’s hair. Had the 75 | queen of Sheba lived in the flat across the airshaft, Della would have 76 | let her hair hang out the window some day to dry just to depreciate Her 77 | Majesty’s jewels and gifts. Had King Solomon been the janitor, with all 78 | his treasures piled up in the basement, Jim would have pulled out his 79 | watch every time he passed, just to see him pluck at his beard from 80 | envy. 81 | 82 | So now Della’s beautiful hair fell about her rippling and shining like 83 | a cascade of brown waters. It reached below her knee and made itself 84 | almost a garment for her. And then she did it up again nervously and 85 | quickly. Once she faltered for a minute and stood still while a tear or 86 | two splashed on the worn red carpet. 87 | 88 | On went her old brown jacket; on went her old brown hat. With a whirl 89 | of skirts and with the brilliant sparkle still in her eyes, she 90 | fluttered out the door and down the stairs to the street. 91 | 92 | Where she stopped the sign read: “Mme. Sofronie. Hair Goods of All 93 | Kinds.” One flight up Della ran, and collected herself, panting. 94 | Madame, large, too white, chilly, hardly looked the “Sofronie.” 95 | 96 | “Will you buy my hair?” asked Della. 97 | 98 | “I buy hair,” said Madame. “Take yer hat off and let’s have a sight at 99 | the looks of it.” 100 | 101 | Down rippled the brown cascade. 102 | 103 | “Twenty dollars,” said Madame, lifting the mass with a practised hand. 104 | 105 | “Give it to me quick,” said Della. 106 | 107 | Oh, and the next two hours tripped by on rosy wings. Forget the hashed 108 | metaphor. She was ransacking the stores for Jim’s present. 109 | 110 | She found it at last. It surely had been made for Jim and no one else. 111 | There was no other like it in any of the stores, and she had turned all 112 | of them inside out. It was a platinum fob chain simple and chaste in 113 | design, properly proclaiming its value by substance alone and not by 114 | meretricious ornamentation—as all good things should do. It was even 115 | worthy of The Watch. As soon as she saw it she knew that it must be 116 | Jim’s. It was like him. Quietness and value—the description applied to 117 | both. Twenty-one dollars they took from her for it, and she hurried 118 | home with the 87 cents. With that chain on his watch Jim might be 119 | properly anxious about the time in any company. Grand as the watch was, 120 | he sometimes looked at it on the sly on account of the old leather 121 | strap that he used in place of a chain. 122 | 123 | When Della reached home her intoxication gave way a little to prudence 124 | and reason. She got out her curling irons and lighted the gas and went 125 | to work repairing the ravages made by generosity added to love. Which 126 | is always a tremendous task, dear friends—a mammoth task. 127 | 128 | Within forty minutes her head was covered with tiny, close-lying curls 129 | that made her look wonderfully like a truant schoolboy. She looked at 130 | her reflection in the mirror long, carefully, and critically. 131 | 132 | “If Jim doesn’t kill me,” she said to herself, “before he takes a 133 | second look at me, he’ll say I look like a Coney Island chorus girl. 134 | But what could I do—oh! what could I do with a dollar and eighty-seven 135 | cents?” 136 | 137 | At 7 o’clock the coffee was made and the frying-pan was on the back of 138 | the stove hot and ready to cook the chops. 139 | 140 | Jim was never late. Della doubled the fob chain in her hand and sat on 141 | the corner of the table near the door that he always entered. Then she 142 | heard his step on the stair away down on the first flight, and she 143 | turned white for just a moment. She had a habit of saying a little 144 | silent prayer about the simplest everyday things, and now she 145 | whispered: “Please God, make him think I am still pretty.” 146 | 147 | The door opened and Jim stepped in and closed it. He looked thin and 148 | very serious. Poor fellow, he was only twenty-two—and to be burdened 149 | with a family! He needed a new overcoat and he was without gloves. 150 | 151 | Jim stopped inside the door, as immovable as a setter at the scent of 152 | quail. His eyes were fixed upon Della, and there was an expression in 153 | them that she could not read, and it terrified her. It was not anger, 154 | nor surprise, nor disapproval, nor horror, nor any of the sentiments 155 | that she had been prepared for. He simply stared at her fixedly with 156 | that peculiar expression on his face. 157 | 158 | Della wriggled off the table and went for him. 159 | 160 | “Jim, darling,” she cried, “don’t look at me that way. I had my hair 161 | cut off and sold because I couldn’t have lived through Christmas 162 | without giving you a present. It’ll grow out again—you won’t mind, will 163 | you? I just had to do it. My hair grows awfully fast. Say ‘Merry 164 | Christmas!’ Jim, and let’s be happy. You don’t know what a nice—what a 165 | beautiful, nice gift I’ve got for you.” 166 | 167 | “You’ve cut off your hair?” asked Jim, laboriously, as if he had not 168 | arrived at that patent fact yet even after the hardest mental labor. 169 | 170 | “Cut it off and sold it,” said Della. “Don’t you like me just as well, 171 | anyhow? I’m me without my hair, ain’t I?” 172 | 173 | Jim looked about the room curiously. 174 | 175 | “You say your hair is gone?” he said, with an air almost of idiocy. 176 | 177 | “You needn’t look for it,” said Della. “It’s sold, I tell you—sold and 178 | gone, too. It’s Christmas Eve, boy. Be good to me, for it went for you. 179 | Maybe the hairs of my head were numbered,” she went on with sudden 180 | serious sweetness, “but nobody could ever count my love for you. Shall 181 | I put the chops on, Jim?” 182 | 183 | Out of his trance Jim seemed quickly to wake. He enfolded his Della. 184 | For ten seconds let us regard with discreet scrutiny some 185 | inconsequential object in the other direction. Eight dollars a week or 186 | a million a year—what is the difference? A mathematician or a wit would 187 | give you the wrong answer. The magi brought valuable gifts, but that 188 | was not among them. This dark assertion will be illuminated later on. 189 | 190 | Jim drew a package from his overcoat pocket and threw it upon the 191 | table. 192 | 193 | “Don’t make any mistake, Dell,” he said, “about me. I don’t think 194 | there’s anything in the way of a haircut or a shave or a shampoo that 195 | could make me like my girl any less. But if you’ll unwrap that package 196 | you may see why you had me going a while at first.” 197 | 198 | White fingers and nimble tore at the string and paper. And then an 199 | ecstatic scream of joy; and then, alas! a quick feminine change to 200 | hysterical tears and wails, necessitating the immediate employment of 201 | all the comforting powers of the lord of the flat. 202 | 203 | For there lay The Combs—the set of combs, side and back, that Della had 204 | worshipped long in a Broadway window. Beautiful combs, pure tortoise 205 | shell, with jewelled rims—just the shade to wear in the beautiful 206 | vanished hair. They were expensive combs, she knew, and her heart had 207 | simply craved and yearned over them without the least hope of 208 | possession. And now, they were hers, but the tresses that should have 209 | adorned the coveted adornments were gone. 210 | 211 | But she hugged them to her bosom, and at length she was able to look up 212 | with dim eyes and a smile and say: “My hair grows so fast, Jim!” 213 | 214 | And then Della leaped up like a little singed cat and cried, “Oh, oh!” 215 | 216 | Jim had not yet seen his beautiful present. She held it out to him 217 | eagerly upon her open palm. The dull precious metal seemed to flash 218 | with a reflection of her bright and ardent spirit. 219 | 220 | “Isn’t it a dandy, Jim? I hunted all over town to find it. You’ll have 221 | to look at the time a hundred times a day now. Give me your watch. I 222 | want to see how it looks on it.” 223 | 224 | Instead of obeying, Jim tumbled down on the couch and put his hands 225 | under the back of his head and smiled. 226 | 227 | “Dell,” said he, “let’s put our Christmas presents away and keep ’em a 228 | while. They’re too nice to use just at present. I sold the watch to get 229 | the money to buy your combs. And now suppose you put the chops on.” 230 | 231 | The magi, as you know, were wise men—wonderfully wise men—who brought 232 | gifts to the Babe in the manger. They invented the art of giving 233 | Christmas presents. Being wise, their gifts were no doubt wise ones, 234 | possibly bearing the privilege of exchange in case of duplication. And 235 | here I have lamely related to you the uneventful chronicle of two 236 | foolish children in a flat who most unwisely sacrificed for each other 237 | the greatest treasures of their house. But in a last word to the wise 238 | of these days let it be said that of all who give gifts these two were 239 | the wisest. Of all who give and receive gifts, such as they are wisest. 240 | Everywhere they are wisest. They are the magi.`] 241 | }, 242 | } 243 | 244 | export default dataFiles; -------------------------------------------------------------------------------- /mockData/determineArguements.js: -------------------------------------------------------------------------------- 1 | //INPUT-> arg2 : string, object or number 2 | //INPUT-> arg3 : string, object or number 3 | //INPUT-> arg4 : string, object or number 4 | //OUTPUT -> Array [Object, Number, 'string] 5 | //description: accepts arguments in any order and returns them in specific order. Can be accessed through array deconstruction( const {parmObj, num, flag} = determineArguements(arg2, arg3, arg4)); 6 | function determineArguements(arg2, arg3, arg4){ 7 | const allArgs = []; 8 | if(arg2) allArgs.push(arg2); 9 | if(arg3) allArgs.push(arg3); 10 | if(arg4) allArgs.push(arg4); 11 | 12 | const result = {parmObj: undefined, num: undefined, flag: undefined}; 13 | allArgs.forEach(el => { 14 | if(!el) return; 15 | if(typeof el === 'object') result.parmObj = el; 16 | if(typeof el === 'number') result.num = el; 17 | if(typeof el === 'string') result.flag = el 18 | }) 19 | if (result.num === undefined) result.num = 1; 20 | return result; 21 | } 22 | 23 | export default determineArguements -------------------------------------------------------------------------------- /mockData/findQueryName.js: -------------------------------------------------------------------------------- 1 | //INPUT -> obj: Object 2 | //OUTPUT: null 3 | //description: Grabs the name of the query from the object that was converted from gql. 4 | function findQueryName(obj){ 5 | //grabing the object within the query search. checks if it is in an array. 6 | let querySearch = Object.keys(obj.data); 7 | return Array.isArray(querySearch) ? querySearch[0] : querySearch; 8 | } 9 | 10 | 11 | export default findQueryName; -------------------------------------------------------------------------------- /mockData/findQueryObject.js: -------------------------------------------------------------------------------- 1 | import findQueryName from "./findQueryName"; 2 | 3 | //INPUT: Object 4 | //OUTPUT: Object 5 | //DESCRIPTION: determines whether the query search returns an array of objects or just an object and only delivers the object. 6 | function findQueryObject(obj){ 7 | let querySearch = findQueryName(obj); 8 | const theObject = obj.data[querySearch]; 9 | let queryObject = Array.isArray(theObject) ? theObject[0] : theObject 10 | return queryObject; 11 | } 12 | 13 | export default findQueryObject; -------------------------------------------------------------------------------- /mockData/insertEntriesIntoObject.js: -------------------------------------------------------------------------------- 1 | //INPUT -> obj: Object 2 | //INPUT -> cache: Object 3 | //Description: recursively goes through the obj and if the Cache has the same key as the obj then the obj is updated 4 | function insertEntriesIntoObject(obj, cache){ 5 | let queryName; 6 | for(const [key, value] of Object.entries(obj)){ 7 | if(Array.isArray(value)){ 8 | queryName = key; 9 | insertEntriesIntoObject(value[0], cache) 10 | } else if(typeof value === 'object'){ 11 | insertEntriesIntoObject(value, cache) 12 | } else if(typeof value === 'string' || typeof value === 'number'){ 13 | if (cache[key]){ 14 | obj[key] = cache[key]; 15 | } 16 | } 17 | } 18 | 19 | return obj; 20 | } 21 | 22 | export default insertEntriesIntoObject; 23 | -------------------------------------------------------------------------------- /mockData/mockQuery.js: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react'; 2 | import attachButtonListener from './attachButtonListener'; 3 | import convertGqlargToObject from './convertGqlargToObject' 4 | import createPopUpWindow from './createPopUpWindow'; 5 | import updateCacheFromSessionStorage from './updateCacheFromSessionStorage'; 6 | import determineArguements from './determineArguements'; 7 | import updateObjWithCache from './updateObjWithCache'; 8 | 9 | 10 | 11 | //INPUT -> gqlSearch : a graphQL search specifically for useQuery hook 12 | //The following can be in any order 13 | //INPUT: number: represents the number of times you want the data duplicated. If you enter 1 or leave empty, then the results will return to you in an object {data: [querysearch]: {results}}, but if you enter a number greater than 2, it will come to you in an array {data: [querysearch]: [{result}, {results duplicated}, etc...]} 14 | //INPUT -> String. Entering "error" will result in an error message. Entering "loading" will result in a loading message. Entering "insert" will result in a pop up window that will allow you to enter personalized data. 15 | //INPUT -> Object. We do nothing with this currently, but you are able to enter an object into the useQuery hook, so we left that in here for future updates. 16 | //OUTPUT -> Object 17 | //description: mockQuery replaces useQuery when you want mockData to test out the front end. Once your backend is set up, discard and continue to use useQuery Hook. 18 | function MockQuery(gqlSearch, arg2, arg3, arg4){ 19 | const {num, paramObj, flag} = determineArguements(arg2, arg3, arg4) 20 | let newObj = convertGqlargToObject(gqlSearch, num); 21 | let pageCache = updateCacheFromSessionStorage(newObj); 22 | updateObjWithCache(newObj, pageCache); 23 | 24 | const [userInput, setUserInput] = useState(JSON.parse(JSON.stringify(newObj))); 25 | 26 | 27 | useEffect(() => { 28 | if(flag === 'insert'){ 29 | setUserInput({loading: true}); 30 | createPopUpWindow(newObj, pageCache); 31 | attachButtonListener(setUserInput, newObj, pageCache); 32 | } 33 | },[]); 34 | 35 | 36 | if(flag === 'error'){ 37 | return {error: 'error from mockQuery'}; 38 | 39 | } else if(flag === 'loading'){ 40 | return {loading: true}; 41 | } 42 | 43 | return userInput 44 | } 45 | 46 | export default MockQuery -------------------------------------------------------------------------------- /mockData/saveCacheToSessionStorage.js: -------------------------------------------------------------------------------- 1 | 2 | //INPUT -> cache: Obj 3 | //OUTPUT: null 4 | //description: saves the object to sessionStorage so that when page is refreshed, data will persist 5 | function saveCacheToSessionStorage(cache){ 6 | sessionStorage.setItem('cache', JSON.stringify(cache)); 7 | } 8 | 9 | export default saveCacheToSessionStorage; -------------------------------------------------------------------------------- /mockData/updateCacheFromSessionStorage.js: -------------------------------------------------------------------------------- 1 | 2 | //INPUT -> obj: Object 3 | //OUTPUT: object 4 | //description: creates an object from the sessionStorage. It can be an empty cache. 5 | function updateCacheFromSessionStorage(obj){ 6 | let newCache = {}; 7 | if(sessionStorage.getItem('cache')){ 8 | newCache = JSON.parse(sessionStorage.getItem('cache')); 9 | } 10 | 11 | return newCache 12 | } 13 | 14 | 15 | 16 | export default updateCacheFromSessionStorage; 17 | -------------------------------------------------------------------------------- /mockData/updateCacheWithUserInput.js: -------------------------------------------------------------------------------- 1 | 2 | //INPUT -> cache: object 3 | //INPUT -> files: object 4 | //OUTPUT -> object 5 | //description: grabs the input from the dom, updates the cache and returns updated cache 6 | function updateCacheWithUserInput(cache, files){ 7 | 8 | const newArr = document.getElementById('mockList').childNodes; //gather all the li elements 9 | newArr.forEach(el => { 10 | const theID = el.id.slice(3) //grabs their id 11 | let newVal = document.getElementById(`${theID}`).value; //grabs the input fields 12 | if(newVal.length){ 13 | if(newVal[0] === "~") newVal = convertEntryWithDataTemplate(newVal.slice(1)) 14 | cache[theID] = newVal || cache[theID] 15 | } 16 | }); 17 | return cache; 18 | 19 | function convertEntryWithDataTemplate(entry){ 20 | const e = entry.toLowerCase(); 21 | let results; 22 | 23 | if(['int', 'integer', 'num', 'number'].includes(e)) results = converterLogic('int', files); 24 | else if(e === 'float') results = converterLogic('float', files); 25 | else if(e === 'boolean') results = converterLogic('boolean', files); 26 | else if(e.slice(0, 4) === 'text') results = converterLogic(parseInt(e.slice(4).replace(/\s+/g, '')), files); 27 | else if(e === 'address') results = converterLogic('address', files); 28 | else if(['phone', 'cell', 'telephone'].includes(e)) results = converterLogic('phone', files); 29 | else if (['photo', 'picture', 'pic', 'thumbnail', 'image', 'img'].includes(e)) results = converterLogic('photo', files); 30 | return results 31 | } 32 | 33 | function converterLogic(input, files){ 34 | if(input === 'float' || input === 'int'){ 35 | files[`${input}`] += 1; 36 | return files[`${input}`] 37 | 38 | } else if(typeof input === 'number'){ 39 | const newString = files.text.item[0].slice(0, input); 40 | return newString; 41 | 42 | } else if(input === 'boolean'){ 43 | return !files.boolean 44 | 45 | } else { 46 | const currObj = files[`${input}`] 47 | return files[`${input}`].item[currObj.index++]; 48 | } 49 | } 50 | } 51 | 52 | 53 | export default updateCacheWithUserInput; -------------------------------------------------------------------------------- /mockData/updateObjWithCache.js: -------------------------------------------------------------------------------- 1 | //INPUT -> obj: Object 2 | //INPUT -> cache: Object 3 | //OUTPUT: null 4 | //Description: iterates over the inputed object -> checks if newer values are in cache, updates and then retruns the obj. 5 | function updateObjWithCache(obj, cache){ 6 | 7 | if(JSON.stringify(cache) === '{}'){ 8 | return obj; 9 | }else{ 10 | iterateObj(obj, cache); 11 | } 12 | 13 | function iterateObj(obj, cache){ 14 | for(const [key, value] of Object.entries(obj)){ 15 | 16 | if(Array.isArray(value)){ 17 | iterateObj(value[0], cache); 18 | 19 | }else if(typeof value === 'string' || typeof value === 'number') { 20 | if(cache[key]){ 21 | obj[key] = cache[key]; 22 | 23 | }else{ 24 | obj[key] = obj[key]; 25 | } 26 | } else{ 27 | iterateObj(value, cache) 28 | } 29 | } 30 | } 31 | }; 32 | 33 | export default updateObjWithCache; 34 | 35 | 36 | // let newObj = { 37 | // "data": { 38 | // "locations": [ 39 | // { 40 | // "id": "id_01", 41 | // "title": "title_01", 42 | // "photo": "photo_01", 43 | // "name": "name_01", 44 | // "description": "description_01", 45 | // "address": "address_01", 46 | // "phone": "phone_01", 47 | // "poster": { 48 | // "person": "person_01", 49 | // "age": "age_01", 50 | // "thumbail": "thumbail_01" 51 | // } 52 | // }, 53 | // { 54 | // "id": "id_01", 55 | // "title": "title_01", 56 | // "photo": "photo_01", 57 | // "name": "name_01", 58 | // "description": "description_01", 59 | // "address": "address_01", 60 | // "phone": "phone_01", 61 | // "poster": { 62 | // "person": "person_01", 63 | // "age": "age_01", 64 | // "thumbail": "thumbail_01" 65 | // } 66 | // }, 67 | // { 68 | // "id": "id_01", 69 | // "title": "title_01", 70 | // "photo": "photo_01", 71 | // "name": "name_01", 72 | // "description": "description_01", 73 | // "address": "address_01", 74 | // "phone": "phone_01", 75 | // "poster": { 76 | // "person": "person_01", 77 | // "age": "age_01", 78 | // "thumbail": "thumbail_01" 79 | // } 80 | // }, 81 | // { 82 | // "id": "id_01", 83 | // "title": "title_01", 84 | // "photo": "photo_01", 85 | // "name": "name_01", 86 | // "description": "description_01", 87 | // "address": "address_01", 88 | // "phone": "phone_01", 89 | // "poster": { 90 | // "person": "person_01", 91 | // "age": "age_01", 92 | // "thumbail": "thumbail_01" 93 | // } 94 | // } 95 | // ] 96 | // } 97 | // } 98 | 99 | // let newCache = { 100 | // "name": "Tim", 101 | // "title": "The best Title Ever", 102 | // "photo": "https://upload.wikimedia.org/wikipedia/commons/3/36/Vassily_Kandinsky%2C_1912_-_Improvisation_27%2C_Garden_of_Love_II.jpg", 103 | // "description": "One dollar and eighty-seven cents.", 104 | // "address": "2300 Oracle Way Austin, TX 78741", 105 | // "phone": "(737)867-1000", 106 | // "person": "Baker99", 107 | // "age": 128, 108 | // "thumbail": "https://upload.wikimedia.org/wikipedia/commons/6/63/Robert_Delaunay%2C_1913%2C_Premier_Disque%2C_134_cm%2C_52.7_inches%2C_Private_collection.jpg" 109 | // } 110 | 111 | // updateObjWithCache(newObj, newCache) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "apolloslibrary", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "MockSchema/index.js", 6 | "bin": { 7 | "create-schema": "./MockSchema/index.js" 8 | }, 9 | "dependencies": { 10 | "ansi-align": "^3.0.1", 11 | "accepts": "^1.3.8", 12 | "apollo-graphql": "^0.9.7", 13 | "ansi-styles": "^3.2.1", 14 | "ansi-regex": "^4.1.1", 15 | "array-flatten": "^1.1.1", 16 | "boxen": "^4.0.0", 17 | "body-parser": "^1.20.0", 18 | "camelcase": "^5.3.1", 19 | "call-bind": "^1.0.2", 20 | "bytes": "^3.1.2", 21 | "chalk": "^2.4.2", 22 | "cli-boxes": "^2.2.1", 23 | "color-convert": "^1.9.3", 24 | "content-disposition": "^0.5.4", 25 | "cliui": "^5.0.0", 26 | "color-name": "^1.1.3", 27 | "content-type": "^1.0.4", 28 | "cookie-signature": "^1.0.6", 29 | "cookie": "^0.5.0", 30 | "core-js-pure": "^3.25.2", 31 | "decamelize": "^1.2.0", 32 | "debug": "^2.6.9", 33 | "depd": "^2.0.0", 34 | "cross-spawn": "^6.0.5", 35 | "ee-first": "^1.1.1", 36 | "emoji-regex": "^7.0.3", 37 | "destroy": "^1.2.0", 38 | "end-of-stream": "^1.4.4", 39 | "encodeurl": "^1.0.2", 40 | "escape-html": "^1.0.3", 41 | "escape-string-regexp": "^1.0.5", 42 | "execa": "^1.0.0", 43 | "etag": "^1.8.1", 44 | "finalhandler": "^1.2.0", 45 | "express": "^4.18.1", 46 | "forwarded": "^0.2.0", 47 | "find-up": "^3.0.0", 48 | "fresh": "^0.5.2", 49 | "function-bind": "^1.1.1", 50 | "get-intrinsic": "^1.1.3", 51 | "get-caller-file": "^2.0.5", 52 | "has": "^1.0.3", 53 | "get-stream": "^4.1.0", 54 | "graphql": "^15.8.0", 55 | "has-flag": "^3.0.0", 56 | "has-symbols": "^1.0.3", 57 | "iconv-lite": "^0.4.24", 58 | "http-errors": "^2.0.0", 59 | "inherits": "^2.0.4", 60 | "is-stream": "^1.1.0", 61 | "invert-kv": "^2.0.0", 62 | "is-fullwidth-code-point": "^2.0.0", 63 | "ipaddr.js": "^1.9.1", 64 | "isexe": "^2.0.0", 65 | "lcid": "^2.0.0", 66 | "locate-path": "^3.0.0", 67 | "lodash.sortby": "^4.7.0", 68 | "media-typer": "^0.3.0", 69 | "map-age-cleaner": "^0.1.3", 70 | "mem": "^4.3.0", 71 | "merge-descriptors": "^1.0.1", 72 | "mime": "^1.6.0", 73 | "methods": "^1.1.2", 74 | "mime-db": "^1.52.0", 75 | "mime-types": "^2.1.35", 76 | "ms": "^2.0.0", 77 | "mimic-fn": "^2.1.0", 78 | "negotiator": "^0.6.3", 79 | "nice-try": "^1.0.5", 80 | "npm-run-path": "^2.0.2", 81 | "on-finished": "^2.4.1", 82 | "p-finally": "^1.0.0", 83 | "os-locale": "^3.1.0", 84 | "p-is-promise": "^2.1.0", 85 | "once": "^1.4.0", 86 | "p-defer": "^1.0.0", 87 | "object-inspect": "^1.12.2", 88 | "p-locate": "^3.0.0", 89 | "p-limit": "^2.3.0", 90 | "path-key": "^2.0.1", 91 | "path-to-regexp": "^0.1.7", 92 | "proxy-addr": "^2.0.7", 93 | "pump": "^3.0.0", 94 | "qs": "^6.10.3", 95 | "raw-body": "^2.5.1", 96 | "range-parser": "^1.2.1", 97 | "readline": "^1.3.0", 98 | "parseurl": "^1.3.3", 99 | "p-try": "^2.2.0", 100 | "path-exists": "^3.0.0", 101 | "require-main-filename": "^2.0.0", 102 | "require-directory": "^2.1.1", 103 | "safe-buffer": "^5.2.1", 104 | "serve-static": "^1.15.0", 105 | "set-blocking": "^2.0.0", 106 | "sha.js": "^2.4.11", 107 | "shebang-command": "^1.2.0", 108 | "shebang-regex": "^1.0.0", 109 | "setprototypeof": "^1.2.0", 110 | "signal-exit": "^3.0.7", 111 | "strip-eof": "^1.0.0", 112 | "semver": "^5.7.1", 113 | "string-width": "^3.1.0", 114 | "statuses": "^2.0.1", 115 | "side-channel": "^1.0.4", 116 | "supports-color": "^5.5.0", 117 | "safer-buffer": "^2.1.2", 118 | "send": "^0.18.0", 119 | "term-size": "^2.2.1", 120 | "type-fest": "^0.5.2", 121 | "which": "^1.3.1", 122 | "utils-merge": "^1.0.1", 123 | "type-is": "^1.6.18", 124 | "unpipe": "^1.0.0", 125 | "vary": "^1.1.2", 126 | "toidentifier": "^1.0.1", 127 | "which-module": "^2.0.0", 128 | "wrap-ansi": "^5.1.0", 129 | "widest-line": "^3.1.0", 130 | "y18n": "^4.0.3", 131 | "wrappy": "^1.0.2", 132 | "strip-ansi": "^5.2.0", 133 | "yargs": "^13.2.4", 134 | "yargs-parser": "^13.1.2" 135 | }, 136 | "devDependencies": {}, 137 | "scripts": { 138 | "test": "echo \"Error: no test specified\" && exit 1" 139 | }, 140 | "author": "", 141 | "license": "MIT" 142 | } --------------------------------------------------------------------------------