├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitattributes ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bin ├── run └── run.cmd ├── example-datasets ├── canonical-user-posts.json ├── chat.js ├── function.js ├── js-db.js ├── mongodb-dataset.js ├── random.js ├── user-post-comment.json └── user-product-order.js ├── package-lock.json ├── package.json ├── src ├── command.js └── import │ ├── check.js │ ├── error.js │ ├── generateTables.js │ ├── import.js │ ├── insert.js │ ├── relationships.js │ ├── sql.js │ └── track.js └── test ├── db.js ├── test.sh └── verify.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.md] 11 | trim_trailing_whitespace = false 12 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | test/db.js 2 | example-datasets 3 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "oclif", 3 | "rules": { 4 | "max-params": "off", 5 | "no-console": "off", 6 | "max-depth": "off", 7 | "one-var": "off", 8 | "complexity": "off", 9 | "unicorn/no-process-exit": "off", 10 | "unicorn/filename-case": "off", 11 | "no-process-exit": "off", 12 | "no-throw-literal": "off", 13 | "node/no-unsupported-features": "off", 14 | "no-warning-comments": "off", 15 | "semi": [1, "always"], 16 | "camelcase": "off", 17 | "guard-for-in": "off" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.js text eol=lf 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *-debug.log 2 | *-error.log 3 | /.nyc_output 4 | /dist 5 | /tmp 6 | /yarn.lock 7 | /test-db.js 8 | test-db 9 | node_modules 10 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Json2GraphQL 2 | 3 | ## Issues 4 | 5 | Please open an issue related to your work. 6 | 7 | ## Local developmet 8 | 9 | 1. Make changes and save 10 | 2. Run the executable in the `bin` directory to test your code. Treat the executable as the command. For example: 11 | 12 | ``` 13 | $ bin/run --help 14 | ``` 15 | 16 | ## Testing 17 | 18 | Please make sure you run the tests before making pull requests. All the pull requests will be run through tests before merging. 19 | 20 | To run the tests locally, you will need an instance of [Hasura GraphQL Engine](https://github.com/hasura/graphql-engine) running. To run the tests, run the command: 21 | 22 | ``` 23 | $ TEST_HGE_URL=https://hge.herokuapp.com npm test 24 | ``` 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [year] [fullname] 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # json2graphql: From a JSON file to postgres-backed GraphQL 2 | 3 | [![oclif](https://img.shields.io/badge/cli-oclif-brightgreen.svg)](https://oclif.io) 4 | [![Version](https://img.shields.io/npm/v/json2graphql.svg)](https://npmjs.org/package/json2graphql) 5 | 6 | `json2graphql` is a tool that imports [a JSON file](#json-structure) to initialise schema and data in Postgres and then allows you to start querying it with GraphQL. 7 | 8 | ![json2graphql - From JSON to GraphQL on Postgres](https://graphql-engine-cdn.hasura.io/assets/json2graphql/json2postgres-graphql.png) 9 | 10 | [Hasura](https://hasura.io) is used to expose a realtime GraphQL API on Postgres. Once your schema and data is imported, you can instantly start running powerful queries with filters, pagination, sorting, fetching relations, insert/update/delete mutations and subscriptions too. 11 | 12 | **Use-cases**: 13 | 14 | - **Bootstrapping a GraphQL backend**: Try out this example of initialising a GraphQL chat backend using a messages/groups/users chat JSON file. [Try it out](#quickly-bootstrap-a-graphql-backend) 15 | - **Play with a mongo dataset in Postgres & GraphQL**: Export a mongo JSON dump, import it to Postgres and start querying it with GraphQL. [Try it out](#play-with-graphql-on-your-mongodb-data) 16 | - **Query existing JSON datasets over GraphQL**: Pick up a JSON dataset, import to your new or existing Hasura/Postgres instance and start querying it. Try using [jdorfman/awesome-json-datasets](https://github.com/jdorfman/awesome-json-datasets). 17 | 18 | ------------------------------------------ 19 | 20 | ## Demo 21 | 22 | ![demo-gif](https://graphql-engine-cdn.hasura.io/assets/json2graphql/j2g.gif) 23 | 24 | In the GIF above, we are importing a schema and data from a JSON database. The Hasura GraphQL Engine is running at `https://j2gtest.herokuapp.com` 25 | 26 | ------------------------------------------ 27 | 28 | - [Quickstart](#quickstart) 29 | - [Installation](#installation) 30 | - [CLI Usage](#cli-usage) 31 | - [JSON Structure](#json-structure) 32 | - [Use Cases](#use-cases) 33 | - [Credits and related projects](#credits-and-related-projects) 34 | 35 | ## Quickstart 36 | 37 | 1. **Create a JSON file** Create a JSON file, say, `db.json` as: 38 | 39 | ```json 40 | { 41 | "post": [ 42 | { "id": 1, "title": "Lorem Ipsum", "views": 254, "user_id": 123 }, 43 | { "id": 2, "title": "Sic Dolor amet", "views": 65, "user_id": 456 } 44 | ], 45 | "user": [ 46 | { "id": 123, "name": "John Doe" }, 47 | { "id": 456, "name": "Alison Craus" } 48 | ], 49 | "comment": [ 50 | { "id": 987, "post_id": 1, "body": "Consectetur adipiscing elit", "user_id": 123 }, 51 | { "id": 995, "post_id": 2, "body": "Nam molestie pellentesque dui", "user_id": 456 }, 52 | { "id": 999, "post_id": 1, "body": "quid agis", "user_id": 456 } 53 | ] 54 | } 55 | ``` 56 | 57 | 2. **Run Hasura + Postgres**: Run the Hasura GraphQL Engine and Postgres on Heroku's free tier by clicking this button: 58 | 59 | [![Deploy to heroku](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/hasura/graphql-engine-heroku) 60 | 61 | Note the URL. It will be of the form: `https://.herokuapp.com`. Let's say it's `j2gtest.herokuapp.com`. 62 | For instructions on how to deploy Hasura in other environments, head to the [docs](https://docs.hasura.io/1.0/graphql/manual/getting-started/index.html). 63 | 64 | 65 | 3. **json2graphql**: We import schema, data and create Hasura configuration in one command: 66 | 67 | ```bash 68 | npm install -g json2graphql 69 | json2graphql https://.herokuapp.com --db=./path/to/db.json 70 | ``` 71 | 72 | 4. **Run GraphQL queries**: You can query the data in Postgres tables over GraphQL using Hasura GraphQL Engine. You can make complicated queries like: 73 | 74 | ```graphql 75 | query { 76 | user { 77 | postsByUserId { 78 | id 79 | title 80 | commentsByPostId { 81 | body 82 | id 83 | } 84 | } 85 | id 86 | } 87 | } 88 | ``` 89 | 90 | 5. **Behind the scenes**: The following schema is created in Postgres:: 91 | 92 | ```sql 93 | 94 | user ( 95 | id integer not null primary key, 96 | name text 97 | ) 98 | 99 | post ( 100 | id integer not null primary key, 101 | title text, 102 | views integer, 103 | user_id integer foreign key references user(id) 104 | ) 105 | 106 | comment ( 107 | id integer not null primary key, 108 | body text, 109 | post_id integer foreign key references post(id), 110 | user_id integer foreign key references user(id) 111 | ) 112 | 113 | ``` 114 | 115 | ## Installation 116 | 117 | ```bash 118 | ## Install globally 119 | npm install -g json2graphql 120 | 121 | ## Or run as a one-off command 122 | npx json2graphql -d ./path/to/db.json 123 | ``` 124 | 125 | ## CLI Usage 126 | 127 | ```bash 128 | # Running against a hasura without an admin secret 129 | json2graphql https://j2gtest.herokuapp.com -d ./path/to/db.json 130 | 131 | # Running against a hasura with an admin secret 132 | json2graphql https://j2gtest.herokuapp.com -s -d ./path/to/db.json 133 | 134 | # Reset configuration, schema & data and import 135 | # Useful for updating schema structure or working against an existing Hasura setup 136 | # WARNING: This will remove all existing schema/data before applying 137 | json2graphql https://j2gtest.herokuapp.com --overwrite -d ./path/to/db.json 138 | ``` 139 | 140 | #### Command 141 | 142 | ```bash 143 | json2graphql URL [flags] 144 | ``` 145 | 146 | #### Args 147 | 148 | * `URL`: The URL where Hasura GraphQL Engine is running 149 | 150 | #### Options 151 | 152 | - `-d --db`: path to the JS file that exports your sample JSON database 153 | - `-o --overwrite`: DANGER: Overwrite tables if they already exist in database 154 | - `-v --version`: show CLI version 155 | - `-h, --help`: show CLI help 156 | 157 | ## JSON structure 158 | 159 | The top level of your JSON database should be a JSON object with keys being the name of entities and values being list of entities. For example: 160 | 161 | ```json 162 | { 163 | "user": [ 164 | { "id": 123, "name": "John Doe" }, 165 | { "id": 456, "name": "Jane Doe" } 166 | ], 167 | "city": [ 168 | { "id": 987, "name": "Stockholm", "country": "Sweden" }, 169 | { "id": 995, "name": "Sydney", "country": "Australia" } 170 | ] 171 | } 172 | ``` 173 | 174 | 1. The JSON structure is a "normalised" set of objects 175 | 2. Top level objects are mapped to tables in postgres and root fields in the GraphQL schema 176 | 3. Keys in the objects are mapped to columns of the tables in postgres, and as fields in the GraphQL schema 177 | 4. Keys in the object with the column name of the form `_id`, are considered to indicate foreign-key constraints on postgres, and connections in the GraphQL schema 178 | 5. The types of the columns/fields are inferred from the data in the columns 179 | json2graphql treats top-level objects as tables, and their keys as columns. If it encounters a column name of the form `_id`, json2graphql will consider it a foreign key to the entity with name ``. 180 | 181 | | JavaScript type (constructor.name) | Postgres column type | GraphQL field type | Example data | 182 | | ---------------------------------- | ---------------------------- | ------------------ | ------------ | 183 | | Number | numeric | numeric | `12.34` or `1223` | 184 | | String | text | String | `Hello world` | 185 | | Boolean | bool | Boolean | true | 186 | | Date | timestamptz | timestamptz | `new Date("Jan 24, 2010 00:00:00")` | 187 | | Object or Array | jsonb | jsonb | { ... } | 188 | 189 | ### Generating data - importing with `.js` files 190 | 191 | You can also use Javascript `.js` files. This allows you to: 192 | - Write some generation logic for sample data 193 | - Use `date` types 194 | 195 | ```js 196 | module.exports = { 197 | user: [1,2,3,4,5].map(i => ({ 198 | id: i, 199 | name: `user-${i}`, 200 | created: new Date() 201 | })) 202 | }; 203 | ``` 204 | 205 | If you need to do some asynchronous stuff before exporting your data, you can 206 | also export an function: 207 | 208 | *Note: You can require [node-fetch](https://www.npmjs.com/package/node-fetch) in your function* 209 | 210 | ```js 211 | const fetch = require('node-fetch'); 212 | 213 | module.exports = async function() { 214 | 215 | const db = await fetch (...) 216 | return db 217 | } 218 | ``` 219 | 220 | ## Use cases 221 | 222 | ### Play with GraphQL on your MongoDB data 223 | 224 | **Note:** This assumes that you've already run through the [quickstart](#quickstart)! 225 | 226 | You can migrate your data from MongoDB and explore Realtime GraphQL over it. 227 | 228 | 1. Tweak the MongoDB doc to fit the required [JSON structure](#json-structure). 229 | 2. Use json2graphql to import the data from the JSON 230 | 3. Make realtime GraphQL queries 231 | 232 | Consider [this MongoDB doc](https://github.com/ozlerhakan/mongodb-json-files/blob/master/datasets/country.json): 233 | 234 | 1. Tweak the doc to fit the required JSON structure. 235 | 236 | The doc originally looks something like this: 237 | 238 | ```js 239 | {"_id":{"$oid":"55a0f42f20a4d760b5fc305e"},"altSpellings":["AI"],"area":91, ... } 240 | {"_id":{"$oid":"55a0f42f20a4d760b5fc305e"},"altSpellings":["AI"],"area":91, ... } 241 | {"_id":{"$oid":"55a0f42f20a4d760b5fc305e"},"altSpellings":["AI"],"area":91, ... } 242 | . 243 | . 244 | . 245 | ``` 246 | 247 | You should wrap it in an array and make the array a value of a top level key of your choice, say, `country`. You should also field name `_id` to `id` because the CLI expects an `id` field. It should look something like this: 248 | 249 | ```js 250 | { 251 | "country": [ 252 | {"id":{"$oid":"55a0f42f20a4d760b5fc305e"},"altSpellings":["AI"],"area":91, ... } 253 | {"id":{"$oid":"55a0f42f20a4d760b5fc305e"},"altSpellings":["AI"],"area":91, ... } 254 | {"id":{"$oid":"55a0f42f20a4d760b5fc305e"},"altSpellings":["AI"],"area":91, ... } 255 | . 256 | . 257 | . 258 | ] 259 | } 260 | ``` 261 | 262 | 2. Use json2graphql to import the data from the JSON to Postgres using Hasura GraphQL Engine: 263 | 264 | ``` 265 | json2graphql https://j2gtest.herokuapp.com -d ./db.js 266 | ``` 267 | 268 | 3. Try realtime GraphQL. Go to your GraphQL Engine console and try making GraphQL queries like so: 269 | 270 | ```gql 271 | query { 272 | country ( 273 | order_by: { name: asc } 274 | limit: 10 275 | where: { capital: { _is_null: false }} 276 | ){ 277 | id 278 | name 279 | area 280 | currency 281 | callingCode 282 | capital 283 | } 284 | } 285 | ``` 286 | 287 | ### Quickly bootstrap a GraphQL Backend 288 | 289 | **Note:** This assumes that you've already run through the [quickstart](#quickstart)! 290 | 291 | You can write your schema and data in JSON format to quickly get a Realtime GraphQL API. 292 | 293 | For example, to start with a group chat backend: 294 | 295 | ``` 296 | { 297 | "user": [ 298 | { "id": 1, "name": "John Doe", "username": "johndoe", "last_seen": new Date() }, 299 | { "id": 2, "name": "Alice Wan", "username": "alisson", "last_seen": new Date() }, 300 | { "id": 3, "name": "Natalie Jackson", "username": "nats", "last_seen": new Date() }, 301 | { "id": 4, "name": "George Walsh", "username": "georgee", "last_seen": new Date() } 302 | ], 303 | "group": [ 304 | { "id": 1, "name": "Engineering", is_active: true }, 305 | { "id": 2, "name": "Marketting", is_active: false } 306 | ], 307 | "message": [ 308 | { "id": 1, group_id: 1, "body": "Message 1", "sent_at": new Date(), "user_id": 1 }, 309 | { "id": 2, group_id: 1, "body": "Message 2", "sent_at": new Date(), "user_id": 2 }, 310 | { "id": 3, group_id: 2, "body": "Message 3", "sent_at": new Date(), "user_id": 3 }, 311 | { "id": 4, group_id: 2, "body": "Message 4", "sent_at": new Date(), "user_id": 4 } 312 | ] 313 | } 314 | ``` 315 | 316 | You can import the above JSON dataset and make queries like: 317 | 318 | ```gql 319 | # fetch all the active groups 320 | query fetch_groups { 321 | group ( 322 | where: {is_active: { _eq: true }} 323 | order_by: { name: asc } 324 | ){ 325 | id 326 | is_active 327 | name 328 | } 329 | } 330 | 331 | # fetch all messages from a group 332 | query fetch_messeges_from_a_group { 333 | message( 334 | where: { group_id: { _eq: 1 }} 335 | order_by: { sent_at: asc } 336 | ) { 337 | id 338 | body 339 | sent_at 340 | sent_by: userByUserId { 341 | id 342 | username 343 | } 344 | } 345 | } 346 | ``` 347 | 348 | ## Examples 349 | 350 | For more examples, check out the [./example-datasets](./example-datasets) directory. 351 | 352 | ## Credits and related projects 353 | 354 | - [Blowson](https://www.blowson.com/docs/) and its creator [Fredi Bach](https://fredibach.ch) 355 | - [firebase2graphql](https://firebase2graphql.com/): A tool to import data from firebase to a realtime GraphQL API on Postgres 356 | - [json-graphql-server](https://github.com/marmelab/json-graphql-server) 357 | -------------------------------------------------------------------------------- /bin/run: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | require('../src/command').run() 4 | .catch(require('@oclif/errors/handle')) 5 | -------------------------------------------------------------------------------- /bin/run.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | node "%~dp0\run" %* 4 | -------------------------------------------------------------------------------- /example-datasets/canonical-user-posts.json: -------------------------------------------------------------------------------- 1 | { 2 | "user": [ 3 | { "id": 456, "name": "Sita K", "address": {"country": "India"}}, 4 | { "id": 123, "name": "John Doe", "address":{"street": "Sesame street", "city":"Timbuktoo", "country": "Mali" }} 5 | ], 6 | "post": [ 7 | { "id": 1, "title": "My first article - user 123", "views": 254, "user_id": 123, "is_published": true }, 8 | { "id": 2, "title": "My first article - user 456", "views": 54, "user_id": 456, "is_published": true}, 9 | { "id": 3, "title": "My second article - user 123", "views": 65, "user_id": 123, "is_published": false}, 10 | { "id": 4, "title": "My second article - user 456", "views": 565, "user_id": 456, "is_published": false} 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /example-datasets/chat.js: -------------------------------------------------------------------------------- 1 | const db = { 2 | "user": [ 3 | { "id": 1, "name": "John Doe", "username": "johndoe", "last_seen": new Date() }, 4 | { "id": 2, "name": "Alice Wan", "username": "alisson", "last_seen": new Date() }, 5 | { "id": 3, "name": "Natalie Jackson", "username": "nats", "last_seen": new Date() }, 6 | { "id": 4, "name": "George Walsh", "username": "georgee", "last_seen": new Date() } 7 | ], 8 | "group": [ 9 | { "id": 1, "name": "Engineering", is_active: true }, 10 | { "id": 2, "name": "Marketting", is_active: false } 11 | ], 12 | "message": [ 13 | { "id": 1, group_id: 1, "body": "Message 1", "sent_at": new Date(), "user_id": 1 }, 14 | { "id": 2, group_id: 1, "body": "Message 2", "sent_at": new Date(), "user_id": 2 }, 15 | { "id": 3, group_id: 2, "body": "Message 3", "sent_at": new Date(), "user_id": 3 }, 16 | { "id": 4, group_id: 2, "body": "Message 4", "sent_at": new Date(), "user_id": 4 } 17 | ] 18 | } 19 | 20 | module.exports = db; -------------------------------------------------------------------------------- /example-datasets/function.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch'); 2 | 3 | const db = async () => { 4 | const response = await fetch( 5 | 'https://bazookaand.herokuapp.com/v1/graphql', 6 | { 7 | method: 'POST', 8 | headers: { 9 | 'x-hasura-access-key': 'advancedbitch' 10 | }, 11 | body: JSON.stringify({ 12 | query: ` 13 | query { 14 | items { 15 | id 16 | item 17 | order_id 18 | } 19 | users { 20 | id 21 | name 22 | balance 23 | } 24 | } 25 | `, 26 | }) 27 | } 28 | ); 29 | const respObj = await response.json(); 30 | return respObj.data; 31 | } 32 | 33 | module.exports = db; -------------------------------------------------------------------------------- /example-datasets/js-db.js: -------------------------------------------------------------------------------- 1 | const db = { 2 | users: [ 3 | {id: 1, name: 'Fredi Bach', country: 'CH', birthday: '1975-09-03', sex: 'm', email: 'osxcode@gmail.com', userStatus_id: 2, date: new Date(), object: {hey: 'there', whats: 'up'}}, 4 | {id: 2, name: 'Samuel Patzen', country: 'CH', birthday: '1978-02-01', sex: 'm', email: 'patzen@bluewin.ch', userStatus_id: 2, date: new Date()}, 5 | {id: 3, name: 'Hans Muster', country: 'CH', birthday: '1978-02-01', sex: 'm', email: 'hans.muster@domain.ch', userStatus_id: 1, date: new Date()}, 6 | ], 7 | userStatus: [ 8 | {id: 1, key: 'inactive'}, 9 | {id: 2, key: 'active'}, 10 | {id: 3, key: 'blocked'}, 11 | ], 12 | userConfigs: [ 13 | {id: 1, users_id: 1}, 14 | ], 15 | leagues: [ 16 | {id: 1, name: 'Switzerland', yearly: true, description: 'Waypoint are all placed in Switzerland by local instructors and top pilots.', created: '2018-05-01', seasonStart: '10-01', seasonEnd: '09-31'}, 17 | {id: 2, name: 'Austria', yearly: true, description: 'Waypoint are all placed in Austria by local instructors and top pilots.', created: '2018-05-02', seasonStart: '10-01', seasonEnd: '09-31'}, 18 | {id: 3, name: 'Vol Liber Grischun Clubmeisterschaft', yearly: false, created: '2018-05-02', seasonStart: '2018-10-01', seasonEnd: '2048-10-01'}, 19 | ], 20 | userLeagues: [ 21 | {id: 1, users_id: 1, leagues_id: 1, isAdmin: true}, 22 | {id: 2, users_id: 1, leagues_id: 2, isAdmin: true}, 23 | {id: 3, users_id: 2, leagues_id: 1}, 24 | {id: 4, users_id: 1, leagues_id: 3}, 25 | {id: 5, users_id: 2, leagues_id: 3, isAdmin: true}, 26 | ], 27 | files: [ 28 | {id: 1, mimetypes_id: 1, width: 250, height: 250, url: 'https://imgplaceholder.com/250x250/cccccc/757575/ion-happy-outline'}, 29 | {id: 2, mimetypes_id: 1, width: 800, height: 400, url: 'https://imgplaceholder.com/800x400/cccccc/757575/fa-image'}, 30 | {id: 3, mimetypes_id: 1, width: 300, height: 200, url: 'https://imgplaceholder.com/300x200/cccccc/757575/fa-map-marker'}, 31 | {id: 4, mimetypes_id: 3, url: 'https://mycdn.com/fredi-bach/2018-07-02-001.igc'}, 32 | {id: 5, mimetypes_id: 3, url: 'https://mycdn.com/fredi-bach/2018-07-03-001.igc'}, 33 | ], 34 | mimetypes: [ 35 | {id: 1, mime: 'image/png', description: 'Portable Network Graphics'}, 36 | {id: 2, mime: 'image/jpeg', description: 'JPEG images'}, 37 | {id: 3, mime: 'application/vnd.fai.igc', description: 'Flight track file'}, 38 | ], 39 | types: [ 40 | {id: 1, name: 'Challenge', description: 'A challenging waypoint, only for the best', points: 200}, 41 | {id: 2, name: 'Altitude', description: 'A big mountain, that needs altitude to reach', points: 150}, 42 | {id: 3, name: 'Beauty', description: 'Just a nice view', points: 100}, 43 | {id: 4, name: 'Takeoff', description: 'Official takoeff', points: 10}, 44 | {id: 5, name: 'Landing', description: 'Official landing', points: 10}, 45 | ], 46 | waypoints: [ 47 | {id: 1, leagues_id: 1, types_id: 1, lat: 3.789, lng: 41.987, radius: 400, points: 100, minAltitude: 3500, name: 'Oberalp Pass', description: 'From Andermatt to Disentis', files_id: 3}, 48 | {id: 2, leagues_id: 1, types_id: 2, lat: 3.589, lng: 41.787, radius: 400, points: 100, minAltitude: 3500, name: 'Furka Pass', description: 'From the Goms to Andermatt', files_id: 3}, 49 | {id: 3, leagues_id: 1, types_id: 4, lat: 3.889, lng: 40.787, radius: 400, points: 10, name: 'Fiesch'}, 50 | ], 51 | waypointNotes: [ 52 | {id: 1, waypoints_id: 1, noteTypes_id: 1, title: 'Föhn', text: 'Bei Föhn sehr gefährlich!'}, 53 | {id: 2, waypoints_id: 1, noteTypes_id: 2, title: 'Basis', text: 'Braucht mindestens 3000 Meter Basis, besser mehr.'}, 54 | ], 55 | waypointPhotos: [ 56 | {id: 1, users_id: 1, official: true, waypoints_id: 1, mimetypes_id: 2, width: 1080, height: 960, url: 'https://mycdn.com/fredi-bach/oberalp-2018-1.jpeg'}, 57 | {id: 2, users_id: 1, official: true, waypoints_id: 1, mimetypes_id: 2, width: 1080, height: 960, url: 'https://mycdn.com/fredi-bach/oberalp-2018-2.jpeg'}, 58 | {id: 3, users_id: 2, official: false, waypoints_id: 1, mimetypes_id: 2, width: 1080, height: 960, url: 'https://mycdn.com/fredi-bach/oberalp-2018-3.jpeg'}, 59 | ], 60 | waypointSuggestions: [ 61 | {id: 1, users_id: 2, leagues_id: 1, types_id: 1, lat: 11.789, lng: 33.987, radius: 800, points: 100, minAltitude: 3500, name: 'Limmeren Stausee', description: 'Auf dem Weg von der Surselva ins Glaernerland', files_id: 3}, 62 | ], 63 | noteTypes: [ 64 | {id: 1, name: 'Wind', icon: 'wind', class: 'waypoint-note-wind'}, 65 | {id: 2, name: 'Altitude', icon: 'altitude', class: 'waypoint-note-altitude'}, 66 | ], 67 | sponsors: [ 68 | {id: 1, waypoints_id: 1, users_id: 1, name: 'Flugschule Appenzell', url: 'http://www.gleitschirm.ch', slogan: 'Die Flugschule im Alpstein.'}, 69 | {id: 2, waypoints_id: 2, name: 'Ozone', url: 'http://www.flyozone.ch', slogan: 'Real world performance.'}, 70 | ], 71 | waypointChats: [ 72 | {id: 1, waypoints_id: 1, users_id: 1, message: 'Can be quite hard with low base!', datetime: '2018-07-02 12:48:45'}, 73 | {id: 2, waypoints_id: 1, users_id: 2, message: 'Oh yes, it can!', datetime: '2018-07-02 12:52:11'}, 74 | ], 75 | wings: [ 76 | {id: 1, model: 'Zeno', brand: 'Ozone', certification: 'D'}, 77 | {id: 2, model: 'Mentor 3', brand: 'Nova', certification: 'B'}, 78 | ], 79 | flights: [ 80 | {id: 1, users_id: 1, leagues_id: 1, wings_id: 1, date: '2018-07-02', score: 200, files_id: 4, comment: 'Bockig!'}, 81 | {id: 2, users_id: 2, leagues_id: 1, wings_id: 2, date: '2018-07-03', score: 100, files_id: 5}, 82 | ], 83 | favoriteFlights: [ 84 | {id: 1, users_id: 1, flights_id: 2, datetime: '2018-07-02 12:48:45'}, 85 | ], 86 | flightWaypoints: [ 87 | {id: 1, flights_id: 1, waypoints_id: 1, datetime: '2018-07-02 12:48:45', score: 100}, 88 | {id: 2, flights_id: 1, waypoints_id: 2, datetime: '2018-07-02 13:11:59', score: 100}, 89 | {id: 3, flights_id: 2, waypoints_id: 2, datetime: '2018-08-02 14:06:11', score: 100}, 90 | ], 91 | flightComments: [ 92 | {id: 1, flights_id: 1, users_id: 2, datetime: '2018-08-02 14:06:11', text: 'Ok, that was nice!'}, 93 | {id: 2, flights_id: 1, users_id: 1, datetime: '2018-08-02 14:09:11', text: 'Thanks'}, 94 | ], 95 | leagueSeasonUserScores: [ 96 | {id: 1, users_id: 1, leagues_id: 1, season: '2018', score: 200, flightCount: 1}, 97 | {id: 2, users_id: 1, leagues_id: 2, season: '2018', score: 0, flightCount: 0}, 98 | {id: 3, users_id: 2, leagues_id: 1, season: '2018', score: 100, flightCount: 1}, 99 | ], 100 | routes: [ 101 | {id: 1, users_id: 1, leagues_id: 1, name: 'Wallis Sightseeing', description: 'A great route for a low wind high cloudbase day.'}, 102 | {id: 2, users_id: 1, leagues_id: 1, name: 'Surselva Adventure'}, 103 | ], 104 | routeWaypoints: [ 105 | {id: 1, routes_id: 1, waypoints_id: 1}, 106 | {id: 2, routes_id: 1, waypoints_id: 2, routeWaypoints_id: 1}, 107 | {id: 3, routes_id: 1, waypoints_id: 3, routeWaypoints_id: 2}, 108 | ], 109 | favoriteRoutes: [ 110 | {id: 1, users_id: 1, routes_id: 1, datetime: '2018-07-01 15:48:45'}, 111 | ], 112 | }; 113 | 114 | module.exports = db; 115 | -------------------------------------------------------------------------------- /example-datasets/user-post-comment.json: -------------------------------------------------------------------------------- 1 | { 2 | "post": [ 3 | { "id": 1, "title": "Lorem Ipsum", "views": 254, "user_id": 123 }, 4 | { "id": 2, "title": "Sic Dolor amet", "views": 65, "user_id": 456 } 5 | ], 6 | "user": [ 7 | { "id": 123, "name": "John Doe" }, 8 | { "id": 456, "name": "Alison Craus" } 9 | ], 10 | "comment": [ 11 | { "id": 987, "post_id": 1, "body": "Consectetur adipiscing elit", "user_id": 123 }, 12 | { "id": 995, "post_id": 2, "body": "Nam molestie pellentesque dui", "user_id": 456 }, 13 | { "id": 999, "post_id": 1, "body": "quid agis", "user_id": 456 } 14 | ] 15 | } -------------------------------------------------------------------------------- /example-datasets/user-product-order.js: -------------------------------------------------------------------------------- 1 | const db = { 2 | user: [ 3 | { id: 1, name: "Jon Doe", date_of_birth: new Date('Jan 8, 1992 00:00:00')}, 4 | { id: 2, name: "Jon Doe", date_of_birth: new Date('May 8, 1982 00:00:00')}, 5 | { id: 3, name: "Jon Doe", date_of_birth: new Date('Dec 8, 1972 00:00:00')} 6 | ], 7 | product: [ 8 | { id: 1, name: "Samsung TV", price: "4000", available: 6}, 9 | { id: 2, name: "Apple TV", price: "8000", available: 2}, 10 | { id: 3, name: "Playstation", price: "800", available: 20} 11 | ], 12 | order: [ 13 | { id: 1, user_id: 1, product_id: 2, placed_at: new Date('Jan 22, 2019 00:12:10')}, 14 | { id: 2, user_id: 3, product_id: 1, placed_at: new Date('Jan 26, 2019 00:12:10')} 15 | ] 16 | } 17 | 18 | module.exports = db; -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json2graphql", 3 | "version": "0.1.5", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@cronvel/get-pixels": { 8 | "version": "3.3.1", 9 | "resolved": "https://registry.npmjs.org/@cronvel/get-pixels/-/get-pixels-3.3.1.tgz", 10 | "integrity": "sha512-jgDb8vGPkpjRDbiYyHTI2Bna4HJysjPNSiERzBnRJjCR/YqC3u0idTae0tmNECsaZLOpAWmlK9wiIwnLGIT9Bg==", 11 | "requires": { 12 | "jpeg-js": "^0.1.1", 13 | "ndarray": "^1.0.13", 14 | "ndarray-pack": "^1.1.1", 15 | "node-bitmap": "0.0.1", 16 | "omggif": "^1.0.5", 17 | "pngjs": "^2.0.0" 18 | } 19 | }, 20 | "@oclif/command": { 21 | "version": "1.4.35", 22 | "resolved": "https://registry.npmjs.org/@oclif/command/-/command-1.4.35.tgz", 23 | "integrity": "sha512-Qpx4JMLBaHya1qdNQXx8zp/4avBumtZGMXBQr2dEsuKADJrcx4gBS9qNX8dlCECRd8DMcZTQLzZ3t/JzL5TU7A==", 24 | "requires": { 25 | "@oclif/errors": "^1.1.2", 26 | "@oclif/parser": "^3.5.2", 27 | "debug": "^3.1.0", 28 | "semver": "^5.5.0" 29 | } 30 | }, 31 | "@oclif/config": { 32 | "version": "1.6.33", 33 | "resolved": "https://registry.npmjs.org/@oclif/config/-/config-1.6.33.tgz", 34 | "integrity": "sha512-6Tgf8mpUQQ/FYDP4EWxuAmNHftt2lWNN1dwEj4I+V3d+tRAIgcAprRUTjc7ZIl9/9e84N5HE4tgCHCqR1UEh8Q==", 35 | "requires": { 36 | "debug": "^3.1.0", 37 | "tslib": "^1.9.2" 38 | } 39 | }, 40 | "@oclif/errors": { 41 | "version": "1.1.2", 42 | "resolved": "https://registry.npmjs.org/@oclif/errors/-/errors-1.1.2.tgz", 43 | "integrity": "sha512-7JGmfL8ob+R+Ut+MQO6qOdj8bUKfbc2HiwR8EeQL6ceK0NA0ch/2tKVkmGYtWZsvc1aqJumWEnCO0FcPMsoQAA==", 44 | "requires": { 45 | "clean-stack": "^1.3.0", 46 | "fs-extra": "^6.0.1", 47 | "indent-string": "^3.2.0", 48 | "strip-ansi": "^4.0.0", 49 | "wrap-ansi": "^3.0.1" 50 | } 51 | }, 52 | "@oclif/linewrap": { 53 | "version": "1.0.0", 54 | "resolved": "https://registry.npmjs.org/@oclif/linewrap/-/linewrap-1.0.0.tgz", 55 | "integrity": "sha512-Ups2dShK52xXa8w6iBWLgcjPJWjais6KPJQq3gQ/88AY6BXoTX+MIGFPrWQO1KLMiQfoTpcLnUwloN4brrVUHw==" 56 | }, 57 | "@oclif/parser": { 58 | "version": "3.7.2", 59 | "resolved": "https://registry.npmjs.org/@oclif/parser/-/parser-3.7.2.tgz", 60 | "integrity": "sha512-ssYXztaf9TuOGCJQOYMg62L1Q4y2lB4wZORWng+Iy0ckP2A6IUnQy97V8YjAJkkohYZOu3Mga8LGfQcf+xdIIw==", 61 | "requires": { 62 | "@oclif/linewrap": "^1.0.0", 63 | "chalk": "^2.4.1", 64 | "tslib": "^1.9.3" 65 | } 66 | }, 67 | "@oclif/plugin-help": { 68 | "version": "2.0.5", 69 | "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-2.0.5.tgz", 70 | "integrity": "sha512-4i7dGI+Jfrmo7g3Ab9B/cE9SfrSibI1ZZtNTh7Dj9sK412pUcS+LmYx2zpfHSy6ZTa8rUnpO7yMmc+a03QKKPA==", 71 | "requires": { 72 | "@oclif/command": "^1.4.30", 73 | "chalk": "^2.4.1", 74 | "indent-string": "^3.2.0", 75 | "lodash.template": "^4.4.0", 76 | "string-width": "^2.1.1", 77 | "widest-line": "^2.0.0", 78 | "wrap-ansi": "^3.0.1" 79 | } 80 | }, 81 | "@oclif/screen": { 82 | "version": "1.0.4", 83 | "resolved": "https://registry.npmjs.org/@oclif/screen/-/screen-1.0.4.tgz", 84 | "integrity": "sha512-60CHpq+eqnTxLZQ4PGHYNwUX572hgpMHGPtTWMjdTMsAvlm69lZV/4ly6O3sAYkomo4NggGcomrDpBe34rxUqw==" 85 | }, 86 | "@types/zen-observable": { 87 | "version": "0.8.0", 88 | "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.0.tgz", 89 | "integrity": "sha512-te5lMAWii1uEJ4FwLjzdlbw3+n0FZNOvFXHxQDKeT0dilh7HOzdMzV2TrJVUzq8ep7J4Na8OUYPRLSQkJHAlrg==" 90 | }, 91 | "accepts": { 92 | "version": "1.3.5", 93 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", 94 | "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", 95 | "requires": { 96 | "mime-types": "~2.1.18", 97 | "negotiator": "0.6.1" 98 | } 99 | }, 100 | "acorn": { 101 | "version": "5.7.3", 102 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", 103 | "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", 104 | "dev": true 105 | }, 106 | "acorn-jsx": { 107 | "version": "3.0.1", 108 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", 109 | "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", 110 | "dev": true, 111 | "requires": { 112 | "acorn": "^3.0.4" 113 | }, 114 | "dependencies": { 115 | "acorn": { 116 | "version": "3.3.0", 117 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", 118 | "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", 119 | "dev": true 120 | } 121 | } 122 | }, 123 | "ajv": { 124 | "version": "5.5.2", 125 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 126 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", 127 | "dev": true, 128 | "requires": { 129 | "co": "^4.6.0", 130 | "fast-deep-equal": "^1.0.0", 131 | "fast-json-stable-stringify": "^2.0.0", 132 | "json-schema-traverse": "^0.3.0" 133 | } 134 | }, 135 | "ajv-keywords": { 136 | "version": "2.1.1", 137 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", 138 | "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", 139 | "dev": true 140 | }, 141 | "ansi-escapes": { 142 | "version": "3.1.0", 143 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", 144 | "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==" 145 | }, 146 | "ansi-regex": { 147 | "version": "3.0.0", 148 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 149 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" 150 | }, 151 | "ansi-styles": { 152 | "version": "3.2.1", 153 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 154 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 155 | "requires": { 156 | "color-convert": "^1.9.0" 157 | } 158 | }, 159 | "ansicolors": { 160 | "version": "0.3.2", 161 | "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", 162 | "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" 163 | }, 164 | "apollo-cache": { 165 | "version": "1.2.1", 166 | "resolved": "https://registry.npmjs.org/apollo-cache/-/apollo-cache-1.2.1.tgz", 167 | "integrity": "sha512-nzFmep/oKlbzUuDyz6fS6aYhRmfpcHWqNkkA9Bbxwk18RD6LXC4eZkuE0gXRX0IibVBHNjYVK+Szi0Yied4SpQ==", 168 | "requires": { 169 | "apollo-utilities": "^1.2.1", 170 | "tslib": "^1.9.3" 171 | } 172 | }, 173 | "apollo-cache-inmemory": { 174 | "version": "1.5.1", 175 | "resolved": "https://registry.npmjs.org/apollo-cache-inmemory/-/apollo-cache-inmemory-1.5.1.tgz", 176 | "integrity": "sha512-D3bdpPmWfaKQkWy8lfwUg+K8OBITo3sx0BHLs1B/9vIdOIZ7JNCKq3EUcAgAfInomJUdN0QG1yOfi8M8hxkN1g==", 177 | "requires": { 178 | "apollo-cache": "^1.2.1", 179 | "apollo-utilities": "^1.2.1", 180 | "optimism": "^0.6.9", 181 | "ts-invariant": "^0.2.1", 182 | "tslib": "^1.9.3" 183 | } 184 | }, 185 | "apollo-client": { 186 | "version": "2.5.1", 187 | "resolved": "https://registry.npmjs.org/apollo-client/-/apollo-client-2.5.1.tgz", 188 | "integrity": "sha512-MNcQKiqLHdGmNJ0rZ0NXaHrToXapJgS/5kPk0FygXt+/FmDCdzqcujI7OPxEC6e9Yw5S/8dIvOXcRNuOMElHkA==", 189 | "requires": { 190 | "@types/zen-observable": "^0.8.0", 191 | "apollo-cache": "1.2.1", 192 | "apollo-link": "^1.0.0", 193 | "apollo-link-dedup": "^1.0.0", 194 | "apollo-utilities": "1.2.1", 195 | "symbol-observable": "^1.0.2", 196 | "ts-invariant": "^0.2.1", 197 | "tslib": "^1.9.3", 198 | "zen-observable": "^0.8.0" 199 | } 200 | }, 201 | "apollo-link": { 202 | "version": "1.2.11", 203 | "resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.11.tgz", 204 | "integrity": "sha512-PQvRCg13VduLy3X/0L79M6uOpTh5iHdxnxYuo8yL7sJlWybKRJwsv4IcRBJpMFbChOOaHY7Og9wgPo6DLKDKDA==", 205 | "requires": { 206 | "apollo-utilities": "^1.2.1", 207 | "ts-invariant": "^0.3.2", 208 | "tslib": "^1.9.3", 209 | "zen-observable-ts": "^0.8.18" 210 | }, 211 | "dependencies": { 212 | "ts-invariant": { 213 | "version": "0.3.2", 214 | "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.3.2.tgz", 215 | "integrity": "sha512-QsY8BCaRnHiB5T6iE4DPlJMAKEG3gzMiUco9FEt1jUXQf0XP6zi0idT0i0rMTu8A326JqNSDsmlkA9dRSh1TRg==", 216 | "requires": { 217 | "tslib": "^1.9.3" 218 | } 219 | } 220 | } 221 | }, 222 | "apollo-link-dedup": { 223 | "version": "1.0.18", 224 | "resolved": "https://registry.npmjs.org/apollo-link-dedup/-/apollo-link-dedup-1.0.18.tgz", 225 | "integrity": "sha512-1rr54wyMTuqUmbWvcXbwduIcaCDcuIgU6MqQ599nAMuTrbSOXthGfoAD8BDTxBGQ9roVlM7ABP0VZVEWRoHWSg==", 226 | "requires": { 227 | "apollo-link": "^1.2.11", 228 | "tslib": "^1.9.3" 229 | } 230 | }, 231 | "apollo-link-http": { 232 | "version": "1.5.14", 233 | "resolved": "https://registry.npmjs.org/apollo-link-http/-/apollo-link-http-1.5.14.tgz", 234 | "integrity": "sha512-XEoPXmGpxFG3wioovgAlPXIarWaW4oWzt8YzjTYZ87R4R7d1A3wKR/KcvkdMV1m5G7YSAHcNkDLe/8hF2nH6cg==", 235 | "requires": { 236 | "apollo-link": "^1.2.11", 237 | "apollo-link-http-common": "^0.2.13", 238 | "tslib": "^1.9.3" 239 | } 240 | }, 241 | "apollo-link-http-common": { 242 | "version": "0.2.13", 243 | "resolved": "https://registry.npmjs.org/apollo-link-http-common/-/apollo-link-http-common-0.2.13.tgz", 244 | "integrity": "sha512-Uyg1ECQpTTA691Fwx5e6Rc/6CPSu4TB4pQRTGIpwZ4l5JDOQ+812Wvi/e3IInmzOZpwx5YrrOfXrtN8BrsDXoA==", 245 | "requires": { 246 | "apollo-link": "^1.2.11", 247 | "ts-invariant": "^0.3.2", 248 | "tslib": "^1.9.3" 249 | }, 250 | "dependencies": { 251 | "ts-invariant": { 252 | "version": "0.3.2", 253 | "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.3.2.tgz", 254 | "integrity": "sha512-QsY8BCaRnHiB5T6iE4DPlJMAKEG3gzMiUco9FEt1jUXQf0XP6zi0idT0i0rMTu8A326JqNSDsmlkA9dRSh1TRg==", 255 | "requires": { 256 | "tslib": "^1.9.3" 257 | } 258 | } 259 | } 260 | }, 261 | "apollo-link-ws": { 262 | "version": "1.0.17", 263 | "resolved": "https://registry.npmjs.org/apollo-link-ws/-/apollo-link-ws-1.0.17.tgz", 264 | "integrity": "sha512-0PKgahM2BOcUiI3QSJMYXOoUylWKzar5NTZLgMLEW4K/CczOTzC4CTXvKMjh/cx57Jto/U2xzKRy9BEoNfnK5Q==", 265 | "requires": { 266 | "apollo-link": "^1.2.11", 267 | "tslib": "^1.9.3" 268 | } 269 | }, 270 | "apollo-utilities": { 271 | "version": "1.2.1", 272 | "resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.2.1.tgz", 273 | "integrity": "sha512-Zv8Udp9XTSFiN8oyXOjf6PMHepD4yxxReLsl6dPUy5Ths7jti3nmlBzZUOxuTWRwZn0MoclqL7RQ5UEJN8MAxg==", 274 | "requires": { 275 | "fast-json-stable-stringify": "^2.0.0", 276 | "ts-invariant": "^0.2.1", 277 | "tslib": "^1.9.3" 278 | } 279 | }, 280 | "argparse": { 281 | "version": "1.0.10", 282 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 283 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 284 | "requires": { 285 | "sprintf-js": "~1.0.2" 286 | } 287 | }, 288 | "array-flatten": { 289 | "version": "1.1.1", 290 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 291 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 292 | }, 293 | "array-union": { 294 | "version": "1.0.2", 295 | "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", 296 | "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", 297 | "dev": true, 298 | "requires": { 299 | "array-uniq": "^1.0.1" 300 | } 301 | }, 302 | "array-uniq": { 303 | "version": "1.0.3", 304 | "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", 305 | "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", 306 | "dev": true 307 | }, 308 | "arrify": { 309 | "version": "1.0.1", 310 | "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", 311 | "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", 312 | "dev": true 313 | }, 314 | "async-limiter": { 315 | "version": "1.0.0", 316 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", 317 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" 318 | }, 319 | "babel-code-frame": { 320 | "version": "6.26.0", 321 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", 322 | "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", 323 | "dev": true, 324 | "requires": { 325 | "chalk": "^1.1.3", 326 | "esutils": "^2.0.2", 327 | "js-tokens": "^3.0.2" 328 | }, 329 | "dependencies": { 330 | "ansi-regex": { 331 | "version": "2.1.1", 332 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 333 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 334 | "dev": true 335 | }, 336 | "ansi-styles": { 337 | "version": "2.2.1", 338 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 339 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", 340 | "dev": true 341 | }, 342 | "chalk": { 343 | "version": "1.1.3", 344 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 345 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 346 | "dev": true, 347 | "requires": { 348 | "ansi-styles": "^2.2.1", 349 | "escape-string-regexp": "^1.0.2", 350 | "has-ansi": "^2.0.0", 351 | "strip-ansi": "^3.0.0", 352 | "supports-color": "^2.0.0" 353 | } 354 | }, 355 | "strip-ansi": { 356 | "version": "3.0.1", 357 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 358 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 359 | "dev": true, 360 | "requires": { 361 | "ansi-regex": "^2.0.0" 362 | } 363 | }, 364 | "supports-color": { 365 | "version": "2.0.0", 366 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 367 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", 368 | "dev": true 369 | } 370 | } 371 | }, 372 | "backo2": { 373 | "version": "1.0.2", 374 | "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", 375 | "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" 376 | }, 377 | "balanced-match": { 378 | "version": "1.0.0", 379 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 380 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 381 | }, 382 | "body-parser": { 383 | "version": "1.18.3", 384 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", 385 | "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", 386 | "requires": { 387 | "bytes": "3.0.0", 388 | "content-type": "~1.0.4", 389 | "debug": "2.6.9", 390 | "depd": "~1.1.2", 391 | "http-errors": "~1.6.3", 392 | "iconv-lite": "0.4.23", 393 | "on-finished": "~2.3.0", 394 | "qs": "6.5.2", 395 | "raw-body": "2.3.3", 396 | "type-is": "~1.6.16" 397 | }, 398 | "dependencies": { 399 | "debug": { 400 | "version": "2.6.9", 401 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 402 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 403 | "requires": { 404 | "ms": "2.0.0" 405 | } 406 | }, 407 | "iconv-lite": { 408 | "version": "0.4.23", 409 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", 410 | "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", 411 | "requires": { 412 | "safer-buffer": ">= 2.1.2 < 3" 413 | } 414 | }, 415 | "ms": { 416 | "version": "2.0.0", 417 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 418 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 419 | } 420 | } 421 | }, 422 | "brace-expansion": { 423 | "version": "1.1.11", 424 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 425 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 426 | "requires": { 427 | "balanced-match": "^1.0.0", 428 | "concat-map": "0.0.1" 429 | } 430 | }, 431 | "buffer-from": { 432 | "version": "1.1.1", 433 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 434 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", 435 | "dev": true 436 | }, 437 | "bytes": { 438 | "version": "3.0.0", 439 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 440 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 441 | }, 442 | "caller-path": { 443 | "version": "0.1.0", 444 | "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", 445 | "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", 446 | "dev": true, 447 | "requires": { 448 | "callsites": "^0.2.0" 449 | } 450 | }, 451 | "callsites": { 452 | "version": "0.2.0", 453 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", 454 | "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", 455 | "dev": true 456 | }, 457 | "cardinal": { 458 | "version": "2.1.1", 459 | "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", 460 | "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", 461 | "requires": { 462 | "ansicolors": "~0.3.2", 463 | "redeyed": "~2.1.0" 464 | } 465 | }, 466 | "chalk": { 467 | "version": "2.4.1", 468 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", 469 | "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", 470 | "requires": { 471 | "ansi-styles": "^3.2.1", 472 | "escape-string-regexp": "^1.0.5", 473 | "supports-color": "^5.3.0" 474 | } 475 | }, 476 | "chardet": { 477 | "version": "0.4.2", 478 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", 479 | "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", 480 | "dev": true 481 | }, 482 | "circular-json": { 483 | "version": "0.3.3", 484 | "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", 485 | "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", 486 | "dev": true 487 | }, 488 | "clean-regexp": { 489 | "version": "1.0.0", 490 | "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", 491 | "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", 492 | "dev": true, 493 | "requires": { 494 | "escape-string-regexp": "^1.0.5" 495 | } 496 | }, 497 | "clean-stack": { 498 | "version": "1.3.0", 499 | "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-1.3.0.tgz", 500 | "integrity": "sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=" 501 | }, 502 | "cli-cursor": { 503 | "version": "2.1.0", 504 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 505 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 506 | "dev": true, 507 | "requires": { 508 | "restore-cursor": "^2.0.0" 509 | } 510 | }, 511 | "cli-ux": { 512 | "version": "4.7.3", 513 | "resolved": "https://registry.npmjs.org/cli-ux/-/cli-ux-4.7.3.tgz", 514 | "integrity": "sha512-JtnkcrM7IDlNcj4EHjkgcEu8UUCwK1VfWfiX6t7N+ICTfIzmbNszwHe6nJCz61mmPQr5bmSEZHHj+sN6+IyEfA==", 515 | "requires": { 516 | "@oclif/linewrap": "^1.0.0", 517 | "@oclif/screen": "^1.0.2", 518 | "ansi-styles": "^3.2.1", 519 | "cardinal": "^2.1.1", 520 | "chalk": "^2.4.1", 521 | "clean-stack": "^1.3.0", 522 | "extract-stack": "^1.0.0", 523 | "fs-extra": "^6.0.1", 524 | "hyperlinker": "^1.0.0", 525 | "indent-string": "^3.2.0", 526 | "is-wsl": "^1.1.0", 527 | "lodash": "^4.17.10", 528 | "password-prompt": "^1.0.6", 529 | "semver": "^5.5.0", 530 | "strip-ansi": "^4.0.0", 531 | "supports-color": "^5.4.0", 532 | "supports-hyperlinks": "^1.0.1" 533 | } 534 | }, 535 | "cli-width": { 536 | "version": "2.2.0", 537 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 538 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", 539 | "dev": true 540 | }, 541 | "co": { 542 | "version": "4.6.0", 543 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 544 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", 545 | "dev": true 546 | }, 547 | "color-convert": { 548 | "version": "1.9.3", 549 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 550 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 551 | "requires": { 552 | "color-name": "1.1.3" 553 | } 554 | }, 555 | "color-name": { 556 | "version": "1.1.3", 557 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 558 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 559 | }, 560 | "concat-map": { 561 | "version": "0.0.1", 562 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 563 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 564 | }, 565 | "concat-stream": { 566 | "version": "1.6.2", 567 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 568 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 569 | "dev": true, 570 | "requires": { 571 | "buffer-from": "^1.0.0", 572 | "inherits": "^2.0.3", 573 | "readable-stream": "^2.2.2", 574 | "typedarray": "^0.0.6" 575 | } 576 | }, 577 | "content-disposition": { 578 | "version": "0.5.2", 579 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 580 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 581 | }, 582 | "content-type": { 583 | "version": "1.0.4", 584 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 585 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 586 | }, 587 | "cookie": { 588 | "version": "0.3.1", 589 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 590 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 591 | }, 592 | "cookie-signature": { 593 | "version": "1.0.6", 594 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 595 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 596 | }, 597 | "core-util-is": { 598 | "version": "1.0.2", 599 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 600 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 601 | "dev": true 602 | }, 603 | "cross-fetch": { 604 | "version": "2.2.2", 605 | "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.2.tgz", 606 | "integrity": "sha1-pH/09/xxLauo9qaVoRyUhEDUVyM=", 607 | "requires": { 608 | "node-fetch": "2.1.2", 609 | "whatwg-fetch": "2.0.4" 610 | }, 611 | "dependencies": { 612 | "node-fetch": { 613 | "version": "2.1.2", 614 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", 615 | "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=" 616 | } 617 | } 618 | }, 619 | "cross-spawn": { 620 | "version": "6.0.5", 621 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 622 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 623 | "requires": { 624 | "nice-try": "^1.0.4", 625 | "path-key": "^2.0.1", 626 | "semver": "^5.5.0", 627 | "shebang-command": "^1.2.0", 628 | "which": "^1.2.9" 629 | } 630 | }, 631 | "cwise-compiler": { 632 | "version": "1.1.3", 633 | "resolved": "https://registry.npmjs.org/cwise-compiler/-/cwise-compiler-1.1.3.tgz", 634 | "integrity": "sha1-9NZnQQ6FDToxOn0tt7HlBbsDTMU=", 635 | "requires": { 636 | "uniq": "^1.0.0" 637 | } 638 | }, 639 | "debug": { 640 | "version": "3.2.5", 641 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.5.tgz", 642 | "integrity": "sha512-D61LaDQPQkxJ5AUM2mbSJRbPkNs/TmdmOeLAi1hgDkpDfIfetSrjmWhccwtuResSwMbACjx/xXQofvM9CE/aeg==", 643 | "requires": { 644 | "ms": "^2.1.1" 645 | } 646 | }, 647 | "deep-is": { 648 | "version": "0.1.3", 649 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 650 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 651 | "dev": true 652 | }, 653 | "del": { 654 | "version": "2.2.2", 655 | "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", 656 | "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", 657 | "dev": true, 658 | "requires": { 659 | "globby": "^5.0.0", 660 | "is-path-cwd": "^1.0.0", 661 | "is-path-in-cwd": "^1.0.0", 662 | "object-assign": "^4.0.1", 663 | "pify": "^2.0.0", 664 | "pinkie-promise": "^2.0.0", 665 | "rimraf": "^2.2.8" 666 | } 667 | }, 668 | "depd": { 669 | "version": "1.1.2", 670 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 671 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 672 | }, 673 | "destroy": { 674 | "version": "1.0.4", 675 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 676 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 677 | }, 678 | "doctrine": { 679 | "version": "2.1.0", 680 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", 681 | "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", 682 | "dev": true, 683 | "requires": { 684 | "esutils": "^2.0.2" 685 | } 686 | }, 687 | "ee-first": { 688 | "version": "1.1.1", 689 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 690 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 691 | }, 692 | "encodeurl": { 693 | "version": "1.0.2", 694 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 695 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 696 | }, 697 | "escape-html": { 698 | "version": "1.0.3", 699 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 700 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 701 | }, 702 | "escape-string-regexp": { 703 | "version": "1.0.5", 704 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 705 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 706 | }, 707 | "eslint": { 708 | "version": "4.19.1", 709 | "resolved": "http://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", 710 | "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", 711 | "dev": true, 712 | "requires": { 713 | "ajv": "^5.3.0", 714 | "babel-code-frame": "^6.22.0", 715 | "chalk": "^2.1.0", 716 | "concat-stream": "^1.6.0", 717 | "cross-spawn": "^5.1.0", 718 | "debug": "^3.1.0", 719 | "doctrine": "^2.1.0", 720 | "eslint-scope": "^3.7.1", 721 | "eslint-visitor-keys": "^1.0.0", 722 | "espree": "^3.5.4", 723 | "esquery": "^1.0.0", 724 | "esutils": "^2.0.2", 725 | "file-entry-cache": "^2.0.0", 726 | "functional-red-black-tree": "^1.0.1", 727 | "glob": "^7.1.2", 728 | "globals": "^11.0.1", 729 | "ignore": "^3.3.3", 730 | "imurmurhash": "^0.1.4", 731 | "inquirer": "^3.0.6", 732 | "is-resolvable": "^1.0.0", 733 | "js-yaml": "^3.9.1", 734 | "json-stable-stringify-without-jsonify": "^1.0.1", 735 | "levn": "^0.3.0", 736 | "lodash": "^4.17.4", 737 | "minimatch": "^3.0.2", 738 | "mkdirp": "^0.5.1", 739 | "natural-compare": "^1.4.0", 740 | "optionator": "^0.8.2", 741 | "path-is-inside": "^1.0.2", 742 | "pluralize": "^7.0.0", 743 | "progress": "^2.0.0", 744 | "regexpp": "^1.0.1", 745 | "require-uncached": "^1.0.3", 746 | "semver": "^5.3.0", 747 | "strip-ansi": "^4.0.0", 748 | "strip-json-comments": "~2.0.1", 749 | "table": "4.0.2", 750 | "text-table": "~0.2.0" 751 | }, 752 | "dependencies": { 753 | "cross-spawn": { 754 | "version": "5.1.0", 755 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", 756 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", 757 | "dev": true, 758 | "requires": { 759 | "lru-cache": "^4.0.1", 760 | "shebang-command": "^1.2.0", 761 | "which": "^1.2.9" 762 | } 763 | } 764 | } 765 | }, 766 | "eslint-ast-utils": { 767 | "version": "1.1.0", 768 | "resolved": "https://registry.npmjs.org/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz", 769 | "integrity": "sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA==", 770 | "dev": true, 771 | "requires": { 772 | "lodash.get": "^4.4.2", 773 | "lodash.zip": "^4.2.0" 774 | } 775 | }, 776 | "eslint-config-oclif": { 777 | "version": "1.5.1", 778 | "resolved": "https://registry.npmjs.org/eslint-config-oclif/-/eslint-config-oclif-1.5.1.tgz", 779 | "integrity": "sha512-r5b8sUuF7wVosygQiuBOZem+P0kCpxeMOw8EPubfcvzMj9OHVZ6boF+a7JvQQNC++R9Pi/Sw3roQxLiAzyur1Q==", 780 | "dev": true, 781 | "requires": { 782 | "eslint-config-xo-space": "^0.18.0", 783 | "eslint-plugin-mocha": "^5.0.0", 784 | "eslint-plugin-node": "^6.0.1", 785 | "eslint-plugin-unicorn": "^4.0.3" 786 | } 787 | }, 788 | "eslint-config-xo": { 789 | "version": "0.20.1", 790 | "resolved": "http://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.20.1.tgz", 791 | "integrity": "sha512-bhDRezvlbYNZn8SHv0WE8aPsdPtH3sq1IU2SznyOtmRwi6e/XQkzs+Kaw1hA9Pz4xmkG796egIsFY2RD6fwUeQ==", 792 | "dev": true 793 | }, 794 | "eslint-config-xo-space": { 795 | "version": "0.18.0", 796 | "resolved": "https://registry.npmjs.org/eslint-config-xo-space/-/eslint-config-xo-space-0.18.0.tgz", 797 | "integrity": "sha512-WtOEyZ4kvs2RDfK2bCQ24qlbJ8Izc/AfkjqD7DqKqXXih2I4brHxIoQwtgDdnbYWgFG4LuS/f6cn7zBE/JVLSw==", 798 | "dev": true, 799 | "requires": { 800 | "eslint-config-xo": "^0.20.0" 801 | } 802 | }, 803 | "eslint-plugin-mocha": { 804 | "version": "5.2.0", 805 | "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-5.2.0.tgz", 806 | "integrity": "sha512-4VTX/qIoxUFRnXLNm6bEhEJyfGnGagmQzV4TWXKzkZgIYyP2FSubEdCjEFTyS/dGwSVRWCWGX7jO7BK8R0kppg==", 807 | "dev": true, 808 | "requires": { 809 | "ramda": "^0.25.0" 810 | } 811 | }, 812 | "eslint-plugin-node": { 813 | "version": "6.0.1", 814 | "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-6.0.1.tgz", 815 | "integrity": "sha512-Q/Cc2sW1OAISDS+Ji6lZS2KV4b7ueA/WydVWd1BECTQwVvfQy5JAi3glhINoKzoMnfnuRgNP+ZWKrGAbp3QDxw==", 816 | "dev": true, 817 | "requires": { 818 | "ignore": "^3.3.6", 819 | "minimatch": "^3.0.4", 820 | "resolve": "^1.3.3", 821 | "semver": "^5.4.1" 822 | } 823 | }, 824 | "eslint-plugin-unicorn": { 825 | "version": "4.0.3", 826 | "resolved": "http://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-4.0.3.tgz", 827 | "integrity": "sha512-F1JMyd42hx4qGhIaVdOSbDyhcxPgTy4BOzctTCkV+hqebPBUOAQn1f5AhMK2LTyiqCmKiTs8huAErbLBSWKoCQ==", 828 | "dev": true, 829 | "requires": { 830 | "clean-regexp": "^1.0.0", 831 | "eslint-ast-utils": "^1.0.0", 832 | "import-modules": "^1.1.0", 833 | "lodash.camelcase": "^4.1.1", 834 | "lodash.kebabcase": "^4.0.1", 835 | "lodash.snakecase": "^4.0.1", 836 | "lodash.upperfirst": "^4.2.0", 837 | "safe-regex": "^1.1.0" 838 | } 839 | }, 840 | "eslint-scope": { 841 | "version": "3.7.3", 842 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", 843 | "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", 844 | "dev": true, 845 | "requires": { 846 | "esrecurse": "^4.1.0", 847 | "estraverse": "^4.1.1" 848 | } 849 | }, 850 | "eslint-visitor-keys": { 851 | "version": "1.0.0", 852 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", 853 | "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", 854 | "dev": true 855 | }, 856 | "espree": { 857 | "version": "3.5.4", 858 | "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", 859 | "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", 860 | "dev": true, 861 | "requires": { 862 | "acorn": "^5.5.0", 863 | "acorn-jsx": "^3.0.0" 864 | } 865 | }, 866 | "esprima": { 867 | "version": "4.0.1", 868 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 869 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" 870 | }, 871 | "esquery": { 872 | "version": "1.0.1", 873 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", 874 | "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", 875 | "dev": true, 876 | "requires": { 877 | "estraverse": "^4.0.0" 878 | } 879 | }, 880 | "esrecurse": { 881 | "version": "4.2.1", 882 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 883 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 884 | "dev": true, 885 | "requires": { 886 | "estraverse": "^4.1.0" 887 | } 888 | }, 889 | "estraverse": { 890 | "version": "4.2.0", 891 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", 892 | "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", 893 | "dev": true 894 | }, 895 | "esutils": { 896 | "version": "2.0.2", 897 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 898 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 899 | "dev": true 900 | }, 901 | "etag": { 902 | "version": "1.8.1", 903 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 904 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 905 | }, 906 | "eventemitter3": { 907 | "version": "3.1.0", 908 | "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", 909 | "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==" 910 | }, 911 | "express": { 912 | "version": "4.16.4", 913 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", 914 | "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", 915 | "requires": { 916 | "accepts": "~1.3.5", 917 | "array-flatten": "1.1.1", 918 | "body-parser": "1.18.3", 919 | "content-disposition": "0.5.2", 920 | "content-type": "~1.0.4", 921 | "cookie": "0.3.1", 922 | "cookie-signature": "1.0.6", 923 | "debug": "2.6.9", 924 | "depd": "~1.1.2", 925 | "encodeurl": "~1.0.2", 926 | "escape-html": "~1.0.3", 927 | "etag": "~1.8.1", 928 | "finalhandler": "1.1.1", 929 | "fresh": "0.5.2", 930 | "merge-descriptors": "1.0.1", 931 | "methods": "~1.1.2", 932 | "on-finished": "~2.3.0", 933 | "parseurl": "~1.3.2", 934 | "path-to-regexp": "0.1.7", 935 | "proxy-addr": "~2.0.4", 936 | "qs": "6.5.2", 937 | "range-parser": "~1.2.0", 938 | "safe-buffer": "5.1.2", 939 | "send": "0.16.2", 940 | "serve-static": "1.13.2", 941 | "setprototypeof": "1.1.0", 942 | "statuses": "~1.4.0", 943 | "type-is": "~1.6.16", 944 | "utils-merge": "1.0.1", 945 | "vary": "~1.1.2" 946 | }, 947 | "dependencies": { 948 | "debug": { 949 | "version": "2.6.9", 950 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 951 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 952 | "requires": { 953 | "ms": "2.0.0" 954 | } 955 | }, 956 | "ms": { 957 | "version": "2.0.0", 958 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 959 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 960 | }, 961 | "safe-buffer": { 962 | "version": "5.1.2", 963 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 964 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 965 | } 966 | } 967 | }, 968 | "external-editor": { 969 | "version": "2.2.0", 970 | "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", 971 | "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", 972 | "dev": true, 973 | "requires": { 974 | "chardet": "^0.4.0", 975 | "iconv-lite": "^0.4.17", 976 | "tmp": "^0.0.33" 977 | } 978 | }, 979 | "extract-stack": { 980 | "version": "1.0.0", 981 | "resolved": "https://registry.npmjs.org/extract-stack/-/extract-stack-1.0.0.tgz", 982 | "integrity": "sha1-uXrK+UQe6iMyUpYktzL8WhyBZfo=" 983 | }, 984 | "fast-deep-equal": { 985 | "version": "1.1.0", 986 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 987 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", 988 | "dev": true 989 | }, 990 | "fast-json-stable-stringify": { 991 | "version": "2.0.0", 992 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 993 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 994 | }, 995 | "fast-levenshtein": { 996 | "version": "2.0.6", 997 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 998 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 999 | "dev": true 1000 | }, 1001 | "figures": { 1002 | "version": "2.0.0", 1003 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 1004 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 1005 | "dev": true, 1006 | "requires": { 1007 | "escape-string-regexp": "^1.0.5" 1008 | } 1009 | }, 1010 | "file-entry-cache": { 1011 | "version": "2.0.0", 1012 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", 1013 | "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", 1014 | "dev": true, 1015 | "requires": { 1016 | "flat-cache": "^1.2.1", 1017 | "object-assign": "^4.0.1" 1018 | } 1019 | }, 1020 | "finalhandler": { 1021 | "version": "1.1.1", 1022 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", 1023 | "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", 1024 | "requires": { 1025 | "debug": "2.6.9", 1026 | "encodeurl": "~1.0.2", 1027 | "escape-html": "~1.0.3", 1028 | "on-finished": "~2.3.0", 1029 | "parseurl": "~1.3.2", 1030 | "statuses": "~1.4.0", 1031 | "unpipe": "~1.0.0" 1032 | }, 1033 | "dependencies": { 1034 | "debug": { 1035 | "version": "2.6.9", 1036 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1037 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1038 | "requires": { 1039 | "ms": "2.0.0" 1040 | } 1041 | }, 1042 | "ms": { 1043 | "version": "2.0.0", 1044 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1045 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1046 | } 1047 | } 1048 | }, 1049 | "flat-cache": { 1050 | "version": "1.3.0", 1051 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", 1052 | "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", 1053 | "dev": true, 1054 | "requires": { 1055 | "circular-json": "^0.3.1", 1056 | "del": "^2.0.2", 1057 | "graceful-fs": "^4.1.2", 1058 | "write": "^0.2.1" 1059 | } 1060 | }, 1061 | "forwarded": { 1062 | "version": "0.1.2", 1063 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 1064 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 1065 | }, 1066 | "fresh": { 1067 | "version": "0.5.2", 1068 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1069 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 1070 | }, 1071 | "fs-extra": { 1072 | "version": "6.0.1", 1073 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz", 1074 | "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==", 1075 | "requires": { 1076 | "graceful-fs": "^4.1.2", 1077 | "jsonfile": "^4.0.0", 1078 | "universalify": "^0.1.0" 1079 | } 1080 | }, 1081 | "fs.realpath": { 1082 | "version": "1.0.0", 1083 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 1084 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 1085 | "dev": true 1086 | }, 1087 | "functional-red-black-tree": { 1088 | "version": "1.0.1", 1089 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 1090 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 1091 | "dev": true 1092 | }, 1093 | "glob": { 1094 | "version": "7.1.3", 1095 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", 1096 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", 1097 | "dev": true, 1098 | "requires": { 1099 | "fs.realpath": "^1.0.0", 1100 | "inflight": "^1.0.4", 1101 | "inherits": "2", 1102 | "minimatch": "^3.0.4", 1103 | "once": "^1.3.0", 1104 | "path-is-absolute": "^1.0.0" 1105 | } 1106 | }, 1107 | "globals": { 1108 | "version": "11.7.0", 1109 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.7.0.tgz", 1110 | "integrity": "sha512-K8BNSPySfeShBQXsahYB/AbbWruVOTyVpgoIDnl8odPpeSfP2J5QO2oLFFdl2j7GfDCtZj2bMKar2T49itTPCg==", 1111 | "dev": true 1112 | }, 1113 | "globby": { 1114 | "version": "5.0.0", 1115 | "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", 1116 | "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", 1117 | "dev": true, 1118 | "requires": { 1119 | "array-union": "^1.0.1", 1120 | "arrify": "^1.0.0", 1121 | "glob": "^7.0.3", 1122 | "object-assign": "^4.0.1", 1123 | "pify": "^2.0.0", 1124 | "pinkie-promise": "^2.0.0" 1125 | } 1126 | }, 1127 | "graceful-fs": { 1128 | "version": "4.1.11", 1129 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 1130 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" 1131 | }, 1132 | "graphql": { 1133 | "version": "0.9.1", 1134 | "resolved": "https://registry.npmjs.org/graphql/-/graphql-0.9.1.tgz", 1135 | "integrity": "sha1-9NFUy+wFTUpdOxvpXyNDXAmqhsg=", 1136 | "requires": { 1137 | "iterall": "1.0.3" 1138 | } 1139 | }, 1140 | "graphql-config": { 1141 | "version": "2.0.1", 1142 | "resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-2.0.1.tgz", 1143 | "integrity": "sha512-eb4FzlODifHE/Q+91QptAmkGw39wL5ToinJ2556UUsGt2drPc4tzifL+HSnHSaxiIbH8EUhc/Fa6+neinF04qA==", 1144 | "requires": { 1145 | "graphql-import": "^0.4.4", 1146 | "graphql-request": "^1.5.0", 1147 | "js-yaml": "^3.10.0", 1148 | "lodash": "^4.17.4", 1149 | "minimatch": "^3.0.4" 1150 | } 1151 | }, 1152 | "graphql-import": { 1153 | "version": "0.4.5", 1154 | "resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.4.5.tgz", 1155 | "integrity": "sha512-G/+I08Qp6/QGTb9qapknCm3yPHV0ZL7wbaalWFpxsfR8ZhZoTBe//LsbsCKlbALQpcMegchpJhpTSKiJjhaVqQ==", 1156 | "requires": { 1157 | "lodash": "^4.17.4" 1158 | } 1159 | }, 1160 | "graphql-language-service-interface": { 1161 | "version": "1.3.2", 1162 | "resolved": "https://registry.npmjs.org/graphql-language-service-interface/-/graphql-language-service-interface-1.3.2.tgz", 1163 | "integrity": "sha512-sOxFV5sBSnYtKIFHtlmAHHVdhok7CRbvCPLcuHvL4Q1RSgKRsPpeHUDKU+yCbmlonOKn/RWEKaYWrUY0Sgv70A==", 1164 | "requires": { 1165 | "graphql-config": "2.0.1", 1166 | "graphql-language-service-parser": "^1.2.2", 1167 | "graphql-language-service-types": "^1.2.2", 1168 | "graphql-language-service-utils": "^1.2.2" 1169 | } 1170 | }, 1171 | "graphql-language-service-parser": { 1172 | "version": "1.2.2", 1173 | "resolved": "https://registry.npmjs.org/graphql-language-service-parser/-/graphql-language-service-parser-1.2.2.tgz", 1174 | "integrity": "sha512-38zMqJibNKeQe3GheyJtBENoXMp+qc29smiiRQtHLZcwnQfsYtu6reJZKxxwzU7XOVh3SedNH15Gf3LjWJVkiQ==", 1175 | "requires": { 1176 | "graphql-config": "2.0.1", 1177 | "graphql-language-service-types": "^1.2.2" 1178 | } 1179 | }, 1180 | "graphql-language-service-types": { 1181 | "version": "1.2.2", 1182 | "resolved": "https://registry.npmjs.org/graphql-language-service-types/-/graphql-language-service-types-1.2.2.tgz", 1183 | "integrity": "sha512-WEAYYCP4jSzbz/Mw0Klc7HHMgtUHLgtaPMV6zyMMmvefCg/yBUkv7wREXKmqF1k1u9+f5ZX3dki0BMaXiwmJug==", 1184 | "requires": { 1185 | "graphql-config": "2.0.1" 1186 | } 1187 | }, 1188 | "graphql-language-service-utils": { 1189 | "version": "1.2.2", 1190 | "resolved": "https://registry.npmjs.org/graphql-language-service-utils/-/graphql-language-service-utils-1.2.2.tgz", 1191 | "integrity": "sha512-98hzn1Dg3sSAiB+TuvNwWAoBrzuHs8NylkTK26TFyBjozM5wBZttp+T08OvOt+9hCFYRa43yRPrWcrs78KH9Hw==", 1192 | "requires": { 1193 | "graphql-config": "2.0.1", 1194 | "graphql-language-service-types": "^1.2.2" 1195 | } 1196 | }, 1197 | "graphql-request": { 1198 | "version": "1.8.2", 1199 | "resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-1.8.2.tgz", 1200 | "integrity": "sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg==", 1201 | "requires": { 1202 | "cross-fetch": "2.2.2" 1203 | } 1204 | }, 1205 | "graphql-tag": { 1206 | "version": "2.10.1", 1207 | "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.10.1.tgz", 1208 | "integrity": "sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg==" 1209 | }, 1210 | "graphqurl": { 1211 | "version": "0.3.3", 1212 | "resolved": "https://registry.npmjs.org/graphqurl/-/graphqurl-0.3.3.tgz", 1213 | "integrity": "sha512-MrWZhLsxUmPAZrZ1owl3GffhjdfEOW11inO2qpDfrHbVd4d6AOpKnIQm3Z3I1hQ1cezZIB6q0C4h22lrY/mk3g==", 1214 | "requires": { 1215 | "@oclif/command": "^1.4.35", 1216 | "@oclif/config": "^1.6.33", 1217 | "@oclif/errors": "^1.1.2", 1218 | "@oclif/plugin-help": "^2.0.5", 1219 | "apollo-cache-inmemory": "^1.2.6", 1220 | "apollo-client": "^2.3.7", 1221 | "apollo-link": "^1.2.2", 1222 | "apollo-link-http": "^1.5.4", 1223 | "apollo-link-ws": "^1.0.8", 1224 | "cli-ux": "^4.7.3", 1225 | "express": "^4.16.3", 1226 | "graphql": "0.9.1", 1227 | "graphql-language-service-interface": "^1.2.2", 1228 | "graphql-language-service-utils": "^1.2.2", 1229 | "graphql-tag": "^2.9.2", 1230 | "node-fetch": "^2.2.0", 1231 | "opn": "^5.3.0", 1232 | "subscriptions-transport-ws": "^0.9.13", 1233 | "terminal-kit": "^1.19.2", 1234 | "ws": "^6.0.0" 1235 | } 1236 | }, 1237 | "has-ansi": { 1238 | "version": "2.0.0", 1239 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 1240 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 1241 | "dev": true, 1242 | "requires": { 1243 | "ansi-regex": "^2.0.0" 1244 | }, 1245 | "dependencies": { 1246 | "ansi-regex": { 1247 | "version": "2.1.1", 1248 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 1249 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 1250 | "dev": true 1251 | } 1252 | } 1253 | }, 1254 | "has-flag": { 1255 | "version": "3.0.0", 1256 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1257 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 1258 | }, 1259 | "http-errors": { 1260 | "version": "1.6.3", 1261 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", 1262 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", 1263 | "requires": { 1264 | "depd": "~1.1.2", 1265 | "inherits": "2.0.3", 1266 | "setprototypeof": "1.1.0", 1267 | "statuses": ">= 1.4.0 < 2" 1268 | } 1269 | }, 1270 | "hyperlinker": { 1271 | "version": "1.0.0", 1272 | "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", 1273 | "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==" 1274 | }, 1275 | "iconv-lite": { 1276 | "version": "0.4.19", 1277 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 1278 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", 1279 | "dev": true 1280 | }, 1281 | "ignore": { 1282 | "version": "3.3.10", 1283 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", 1284 | "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", 1285 | "dev": true 1286 | }, 1287 | "immutable-tuple": { 1288 | "version": "0.4.10", 1289 | "resolved": "https://registry.npmjs.org/immutable-tuple/-/immutable-tuple-0.4.10.tgz", 1290 | "integrity": "sha512-45jheDbc3Kr5Cw8EtDD+4woGRUV0utIrJBZT8XH0TPZRfm8tzT0/sLGGzyyCCFqFMG5Pv5Igf3WY/arn6+8V9Q==" 1291 | }, 1292 | "import-modules": { 1293 | "version": "1.1.0", 1294 | "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-1.1.0.tgz", 1295 | "integrity": "sha1-dI23nFzEK7lwHvq0JPiU5yYA6dw=", 1296 | "dev": true 1297 | }, 1298 | "imurmurhash": { 1299 | "version": "0.1.4", 1300 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1301 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 1302 | "dev": true 1303 | }, 1304 | "indent-string": { 1305 | "version": "3.2.0", 1306 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", 1307 | "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=" 1308 | }, 1309 | "inflight": { 1310 | "version": "1.0.6", 1311 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 1312 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 1313 | "dev": true, 1314 | "requires": { 1315 | "once": "^1.3.0", 1316 | "wrappy": "1" 1317 | } 1318 | }, 1319 | "inherits": { 1320 | "version": "2.0.3", 1321 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 1322 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 1323 | }, 1324 | "inquirer": { 1325 | "version": "3.3.0", 1326 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", 1327 | "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", 1328 | "dev": true, 1329 | "requires": { 1330 | "ansi-escapes": "^3.0.0", 1331 | "chalk": "^2.0.0", 1332 | "cli-cursor": "^2.1.0", 1333 | "cli-width": "^2.0.0", 1334 | "external-editor": "^2.0.4", 1335 | "figures": "^2.0.0", 1336 | "lodash": "^4.3.0", 1337 | "mute-stream": "0.0.7", 1338 | "run-async": "^2.2.0", 1339 | "rx-lite": "^4.0.8", 1340 | "rx-lite-aggregates": "^4.0.8", 1341 | "string-width": "^2.1.0", 1342 | "strip-ansi": "^4.0.0", 1343 | "through": "^2.3.6" 1344 | } 1345 | }, 1346 | "iota-array": { 1347 | "version": "1.0.0", 1348 | "resolved": "https://registry.npmjs.org/iota-array/-/iota-array-1.0.0.tgz", 1349 | "integrity": "sha1-ge9X/l0FgUzVjCSDYyqZwwoOgIc=" 1350 | }, 1351 | "ipaddr.js": { 1352 | "version": "1.8.0", 1353 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", 1354 | "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" 1355 | }, 1356 | "is-buffer": { 1357 | "version": "1.1.6", 1358 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", 1359 | "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" 1360 | }, 1361 | "is-fullwidth-code-point": { 1362 | "version": "2.0.0", 1363 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1364 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 1365 | }, 1366 | "is-path-cwd": { 1367 | "version": "1.0.0", 1368 | "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", 1369 | "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", 1370 | "dev": true 1371 | }, 1372 | "is-path-in-cwd": { 1373 | "version": "1.0.1", 1374 | "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", 1375 | "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", 1376 | "dev": true, 1377 | "requires": { 1378 | "is-path-inside": "^1.0.0" 1379 | } 1380 | }, 1381 | "is-path-inside": { 1382 | "version": "1.0.1", 1383 | "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", 1384 | "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", 1385 | "dev": true, 1386 | "requires": { 1387 | "path-is-inside": "^1.0.1" 1388 | } 1389 | }, 1390 | "is-promise": { 1391 | "version": "2.1.0", 1392 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 1393 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", 1394 | "dev": true 1395 | }, 1396 | "is-resolvable": { 1397 | "version": "1.1.0", 1398 | "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", 1399 | "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", 1400 | "dev": true 1401 | }, 1402 | "is-wsl": { 1403 | "version": "1.1.0", 1404 | "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", 1405 | "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" 1406 | }, 1407 | "isarray": { 1408 | "version": "1.0.0", 1409 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 1410 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 1411 | "dev": true 1412 | }, 1413 | "isexe": { 1414 | "version": "2.0.0", 1415 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1416 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 1417 | }, 1418 | "iterall": { 1419 | "version": "1.0.3", 1420 | "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.0.3.tgz", 1421 | "integrity": "sha1-4LMZWPg1ATwyP/CxCUOCmsaapLc=" 1422 | }, 1423 | "jpeg-js": { 1424 | "version": "0.1.2", 1425 | "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.1.2.tgz", 1426 | "integrity": "sha1-E1uZLAV1yYXPoPSUoyJ+0jhYPs4=" 1427 | }, 1428 | "js-tokens": { 1429 | "version": "3.0.2", 1430 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", 1431 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", 1432 | "dev": true 1433 | }, 1434 | "js-yaml": { 1435 | "version": "3.13.1", 1436 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 1437 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 1438 | "requires": { 1439 | "argparse": "^1.0.7", 1440 | "esprima": "^4.0.0" 1441 | } 1442 | }, 1443 | "json-schema-traverse": { 1444 | "version": "0.3.1", 1445 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 1446 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", 1447 | "dev": true 1448 | }, 1449 | "json-stable-stringify-without-jsonify": { 1450 | "version": "1.0.1", 1451 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1452 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 1453 | "dev": true 1454 | }, 1455 | "jsonfile": { 1456 | "version": "4.0.0", 1457 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 1458 | "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", 1459 | "requires": { 1460 | "graceful-fs": "^4.1.6" 1461 | } 1462 | }, 1463 | "lazyness": { 1464 | "version": "1.1.1", 1465 | "resolved": "https://registry.npmjs.org/lazyness/-/lazyness-1.1.1.tgz", 1466 | "integrity": "sha512-rYHC6l6LeRlJSt5jxpqN8z/49gZ0CqLi89HAGzJjHahCFlqEjFGFN9O15hmzSzUGFl7zN/vOWduv/+0af3r/kQ==" 1467 | }, 1468 | "levn": { 1469 | "version": "0.3.0", 1470 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 1471 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 1472 | "dev": true, 1473 | "requires": { 1474 | "prelude-ls": "~1.1.2", 1475 | "type-check": "~0.3.2" 1476 | } 1477 | }, 1478 | "lodash": { 1479 | "version": "4.17.15", 1480 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 1481 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" 1482 | }, 1483 | "lodash._reinterpolate": { 1484 | "version": "3.0.0", 1485 | "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", 1486 | "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" 1487 | }, 1488 | "lodash.camelcase": { 1489 | "version": "4.3.0", 1490 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", 1491 | "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", 1492 | "dev": true 1493 | }, 1494 | "lodash.get": { 1495 | "version": "4.4.2", 1496 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", 1497 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", 1498 | "dev": true 1499 | }, 1500 | "lodash.kebabcase": { 1501 | "version": "4.1.1", 1502 | "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", 1503 | "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", 1504 | "dev": true 1505 | }, 1506 | "lodash.snakecase": { 1507 | "version": "4.1.1", 1508 | "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", 1509 | "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=", 1510 | "dev": true 1511 | }, 1512 | "lodash.template": { 1513 | "version": "4.4.0", 1514 | "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", 1515 | "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", 1516 | "requires": { 1517 | "lodash._reinterpolate": "~3.0.0", 1518 | "lodash.templatesettings": "^4.0.0" 1519 | } 1520 | }, 1521 | "lodash.templatesettings": { 1522 | "version": "4.1.0", 1523 | "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", 1524 | "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", 1525 | "requires": { 1526 | "lodash._reinterpolate": "~3.0.0" 1527 | } 1528 | }, 1529 | "lodash.upperfirst": { 1530 | "version": "4.3.1", 1531 | "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", 1532 | "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=", 1533 | "dev": true 1534 | }, 1535 | "lodash.zip": { 1536 | "version": "4.2.0", 1537 | "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", 1538 | "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=", 1539 | "dev": true 1540 | }, 1541 | "lru-cache": { 1542 | "version": "4.1.3", 1543 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", 1544 | "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", 1545 | "dev": true, 1546 | "requires": { 1547 | "pseudomap": "^1.0.2", 1548 | "yallist": "^2.1.2" 1549 | } 1550 | }, 1551 | "media-typer": { 1552 | "version": "0.3.0", 1553 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1554 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 1555 | }, 1556 | "merge-descriptors": { 1557 | "version": "1.0.1", 1558 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1559 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 1560 | }, 1561 | "methods": { 1562 | "version": "1.1.2", 1563 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1564 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 1565 | }, 1566 | "mime": { 1567 | "version": "1.4.1", 1568 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", 1569 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" 1570 | }, 1571 | "mime-db": { 1572 | "version": "1.38.0", 1573 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", 1574 | "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==" 1575 | }, 1576 | "mime-types": { 1577 | "version": "2.1.22", 1578 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", 1579 | "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", 1580 | "requires": { 1581 | "mime-db": "~1.38.0" 1582 | } 1583 | }, 1584 | "mimic-fn": { 1585 | "version": "1.2.0", 1586 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 1587 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", 1588 | "dev": true 1589 | }, 1590 | "minimatch": { 1591 | "version": "3.0.4", 1592 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1593 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1594 | "requires": { 1595 | "brace-expansion": "^1.1.7" 1596 | } 1597 | }, 1598 | "minimist": { 1599 | "version": "0.0.8", 1600 | "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1601 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 1602 | "dev": true 1603 | }, 1604 | "mkdirp": { 1605 | "version": "0.5.1", 1606 | "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1607 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 1608 | "dev": true, 1609 | "requires": { 1610 | "minimist": "0.0.8" 1611 | } 1612 | }, 1613 | "moment": { 1614 | "version": "2.22.2", 1615 | "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", 1616 | "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" 1617 | }, 1618 | "ms": { 1619 | "version": "2.1.1", 1620 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 1621 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 1622 | }, 1623 | "mute-stream": { 1624 | "version": "0.0.7", 1625 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 1626 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", 1627 | "dev": true 1628 | }, 1629 | "natural-compare": { 1630 | "version": "1.4.0", 1631 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1632 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 1633 | "dev": true 1634 | }, 1635 | "ndarray": { 1636 | "version": "1.0.18", 1637 | "resolved": "https://registry.npmjs.org/ndarray/-/ndarray-1.0.18.tgz", 1638 | "integrity": "sha1-tg06cyJOxVXQ+qeXEeUCRI/T95M=", 1639 | "requires": { 1640 | "iota-array": "^1.0.0", 1641 | "is-buffer": "^1.0.2" 1642 | } 1643 | }, 1644 | "ndarray-pack": { 1645 | "version": "1.2.1", 1646 | "resolved": "https://registry.npmjs.org/ndarray-pack/-/ndarray-pack-1.2.1.tgz", 1647 | "integrity": "sha1-jK6+qqJNXs9w/4YCBjeXfajuWFo=", 1648 | "requires": { 1649 | "cwise-compiler": "^1.1.2", 1650 | "ndarray": "^1.0.13" 1651 | } 1652 | }, 1653 | "negotiator": { 1654 | "version": "0.6.1", 1655 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 1656 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" 1657 | }, 1658 | "nextgen-events": { 1659 | "version": "1.1.0", 1660 | "resolved": "https://registry.npmjs.org/nextgen-events/-/nextgen-events-1.1.0.tgz", 1661 | "integrity": "sha512-Emz5rh584fygInd3gtwP+xGyJhEnyxQa0/Xbmw8sbpXVGV/luqDnVPq1cQopYR7qg6KUlPfwWVhxrhZri1wDAw==" 1662 | }, 1663 | "nice-try": { 1664 | "version": "1.0.5", 1665 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 1666 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" 1667 | }, 1668 | "node-bitmap": { 1669 | "version": "0.0.1", 1670 | "resolved": "https://registry.npmjs.org/node-bitmap/-/node-bitmap-0.0.1.tgz", 1671 | "integrity": "sha1-GA6scAPgxwdhjvMTaPYvhLKmkJE=" 1672 | }, 1673 | "node-fetch": { 1674 | "version": "2.2.0", 1675 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.2.0.tgz", 1676 | "integrity": "sha512-OayFWziIxiHY8bCUyLX6sTpDH8Jsbp4FfYd1j1f7vZyfgkcOnAyM4oQR16f8a0s7Gl/viMGRey8eScYk4V4EZA==" 1677 | }, 1678 | "object-assign": { 1679 | "version": "4.1.1", 1680 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1681 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 1682 | "dev": true 1683 | }, 1684 | "omggif": { 1685 | "version": "1.0.9", 1686 | "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.9.tgz", 1687 | "integrity": "sha1-3LcCTazVDFK00wPwSALJHAV8dl8=" 1688 | }, 1689 | "on-finished": { 1690 | "version": "2.3.0", 1691 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1692 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1693 | "requires": { 1694 | "ee-first": "1.1.1" 1695 | } 1696 | }, 1697 | "once": { 1698 | "version": "1.4.0", 1699 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1700 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1701 | "dev": true, 1702 | "requires": { 1703 | "wrappy": "1" 1704 | } 1705 | }, 1706 | "onetime": { 1707 | "version": "2.0.1", 1708 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 1709 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 1710 | "dev": true, 1711 | "requires": { 1712 | "mimic-fn": "^1.0.0" 1713 | } 1714 | }, 1715 | "opn": { 1716 | "version": "5.4.0", 1717 | "resolved": "https://registry.npmjs.org/opn/-/opn-5.4.0.tgz", 1718 | "integrity": "sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw==", 1719 | "requires": { 1720 | "is-wsl": "^1.1.0" 1721 | } 1722 | }, 1723 | "optimism": { 1724 | "version": "0.6.9", 1725 | "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.6.9.tgz", 1726 | "integrity": "sha512-xoQm2lvXbCA9Kd7SCx6y713Y7sZ6fUc5R6VYpoL5M6svKJbTuvtNopexK8sO8K4s0EOUYHuPN2+yAEsNyRggkQ==", 1727 | "requires": { 1728 | "immutable-tuple": "^0.4.9" 1729 | } 1730 | }, 1731 | "optionator": { 1732 | "version": "0.8.2", 1733 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 1734 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 1735 | "dev": true, 1736 | "requires": { 1737 | "deep-is": "~0.1.3", 1738 | "fast-levenshtein": "~2.0.4", 1739 | "levn": "~0.3.0", 1740 | "prelude-ls": "~1.1.2", 1741 | "type-check": "~0.3.2", 1742 | "wordwrap": "~1.0.0" 1743 | } 1744 | }, 1745 | "os-tmpdir": { 1746 | "version": "1.0.2", 1747 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 1748 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 1749 | "dev": true 1750 | }, 1751 | "parseurl": { 1752 | "version": "1.3.2", 1753 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 1754 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" 1755 | }, 1756 | "password-prompt": { 1757 | "version": "1.0.7", 1758 | "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.0.7.tgz", 1759 | "integrity": "sha1-jid0jTQAvJyRQNWt5wXft6632Ro=", 1760 | "requires": { 1761 | "ansi-escapes": "^3.1.0", 1762 | "cross-spawn": "^6.0.5" 1763 | } 1764 | }, 1765 | "path-is-absolute": { 1766 | "version": "1.0.1", 1767 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1768 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1769 | "dev": true 1770 | }, 1771 | "path-is-inside": { 1772 | "version": "1.0.2", 1773 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 1774 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", 1775 | "dev": true 1776 | }, 1777 | "path-key": { 1778 | "version": "2.0.1", 1779 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 1780 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" 1781 | }, 1782 | "path-parse": { 1783 | "version": "1.0.6", 1784 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 1785 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 1786 | "dev": true 1787 | }, 1788 | "path-to-regexp": { 1789 | "version": "0.1.7", 1790 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1791 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 1792 | }, 1793 | "pify": { 1794 | "version": "2.3.0", 1795 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1796 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", 1797 | "dev": true 1798 | }, 1799 | "pinkie": { 1800 | "version": "2.0.4", 1801 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 1802 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", 1803 | "dev": true 1804 | }, 1805 | "pinkie-promise": { 1806 | "version": "2.0.1", 1807 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 1808 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 1809 | "dev": true, 1810 | "requires": { 1811 | "pinkie": "^2.0.0" 1812 | } 1813 | }, 1814 | "pluralize": { 1815 | "version": "7.0.0", 1816 | "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", 1817 | "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", 1818 | "dev": true 1819 | }, 1820 | "pngjs": { 1821 | "version": "2.3.1", 1822 | "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-2.3.1.tgz", 1823 | "integrity": "sha1-EdHhK5y2TWPjDBQ6Mw9MH1Z9qF8=" 1824 | }, 1825 | "prelude-ls": { 1826 | "version": "1.1.2", 1827 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1828 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 1829 | "dev": true 1830 | }, 1831 | "process-nextick-args": { 1832 | "version": "2.0.0", 1833 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 1834 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", 1835 | "dev": true 1836 | }, 1837 | "progress": { 1838 | "version": "2.0.0", 1839 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", 1840 | "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", 1841 | "dev": true 1842 | }, 1843 | "proxy-addr": { 1844 | "version": "2.0.4", 1845 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", 1846 | "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", 1847 | "requires": { 1848 | "forwarded": "~0.1.2", 1849 | "ipaddr.js": "1.8.0" 1850 | } 1851 | }, 1852 | "pseudomap": { 1853 | "version": "1.0.2", 1854 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 1855 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", 1856 | "dev": true 1857 | }, 1858 | "qs": { 1859 | "version": "6.5.2", 1860 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 1861 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 1862 | }, 1863 | "ramda": { 1864 | "version": "0.25.0", 1865 | "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", 1866 | "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==", 1867 | "dev": true 1868 | }, 1869 | "range-parser": { 1870 | "version": "1.2.0", 1871 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 1872 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 1873 | }, 1874 | "raw-body": { 1875 | "version": "2.3.3", 1876 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", 1877 | "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", 1878 | "requires": { 1879 | "bytes": "3.0.0", 1880 | "http-errors": "1.6.3", 1881 | "iconv-lite": "0.4.23", 1882 | "unpipe": "1.0.0" 1883 | }, 1884 | "dependencies": { 1885 | "iconv-lite": { 1886 | "version": "0.4.23", 1887 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", 1888 | "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", 1889 | "requires": { 1890 | "safer-buffer": ">= 2.1.2 < 3" 1891 | } 1892 | } 1893 | } 1894 | }, 1895 | "readable-stream": { 1896 | "version": "2.3.6", 1897 | "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 1898 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 1899 | "dev": true, 1900 | "requires": { 1901 | "core-util-is": "~1.0.0", 1902 | "inherits": "~2.0.3", 1903 | "isarray": "~1.0.0", 1904 | "process-nextick-args": "~2.0.0", 1905 | "safe-buffer": "~5.1.1", 1906 | "string_decoder": "~1.1.1", 1907 | "util-deprecate": "~1.0.1" 1908 | } 1909 | }, 1910 | "redeyed": { 1911 | "version": "2.1.1", 1912 | "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", 1913 | "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", 1914 | "requires": { 1915 | "esprima": "~4.0.0" 1916 | } 1917 | }, 1918 | "regexpp": { 1919 | "version": "1.1.0", 1920 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", 1921 | "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", 1922 | "dev": true 1923 | }, 1924 | "require-uncached": { 1925 | "version": "1.0.3", 1926 | "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", 1927 | "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", 1928 | "dev": true, 1929 | "requires": { 1930 | "caller-path": "^0.1.0", 1931 | "resolve-from": "^1.0.0" 1932 | } 1933 | }, 1934 | "resolve": { 1935 | "version": "1.8.1", 1936 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", 1937 | "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", 1938 | "dev": true, 1939 | "requires": { 1940 | "path-parse": "^1.0.5" 1941 | } 1942 | }, 1943 | "resolve-from": { 1944 | "version": "1.0.1", 1945 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", 1946 | "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", 1947 | "dev": true 1948 | }, 1949 | "restore-cursor": { 1950 | "version": "2.0.0", 1951 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 1952 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 1953 | "dev": true, 1954 | "requires": { 1955 | "onetime": "^2.0.0", 1956 | "signal-exit": "^3.0.2" 1957 | } 1958 | }, 1959 | "ret": { 1960 | "version": "0.1.15", 1961 | "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", 1962 | "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", 1963 | "dev": true 1964 | }, 1965 | "rimraf": { 1966 | "version": "2.6.2", 1967 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", 1968 | "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", 1969 | "dev": true, 1970 | "requires": { 1971 | "glob": "^7.0.5" 1972 | } 1973 | }, 1974 | "run-async": { 1975 | "version": "2.3.0", 1976 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 1977 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 1978 | "dev": true, 1979 | "requires": { 1980 | "is-promise": "^2.1.0" 1981 | } 1982 | }, 1983 | "rx-lite": { 1984 | "version": "4.0.8", 1985 | "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", 1986 | "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", 1987 | "dev": true 1988 | }, 1989 | "rx-lite-aggregates": { 1990 | "version": "4.0.8", 1991 | "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", 1992 | "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", 1993 | "dev": true, 1994 | "requires": { 1995 | "rx-lite": "*" 1996 | } 1997 | }, 1998 | "safe-buffer": { 1999 | "version": "5.1.1", 2000 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 2001 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", 2002 | "dev": true 2003 | }, 2004 | "safe-regex": { 2005 | "version": "1.1.0", 2006 | "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", 2007 | "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", 2008 | "dev": true, 2009 | "requires": { 2010 | "ret": "~0.1.10" 2011 | } 2012 | }, 2013 | "safer-buffer": { 2014 | "version": "2.1.2", 2015 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 2016 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 2017 | }, 2018 | "semver": { 2019 | "version": "5.5.1", 2020 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", 2021 | "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==" 2022 | }, 2023 | "send": { 2024 | "version": "0.16.2", 2025 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", 2026 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", 2027 | "requires": { 2028 | "debug": "2.6.9", 2029 | "depd": "~1.1.2", 2030 | "destroy": "~1.0.4", 2031 | "encodeurl": "~1.0.2", 2032 | "escape-html": "~1.0.3", 2033 | "etag": "~1.8.1", 2034 | "fresh": "0.5.2", 2035 | "http-errors": "~1.6.2", 2036 | "mime": "1.4.1", 2037 | "ms": "2.0.0", 2038 | "on-finished": "~2.3.0", 2039 | "range-parser": "~1.2.0", 2040 | "statuses": "~1.4.0" 2041 | }, 2042 | "dependencies": { 2043 | "debug": { 2044 | "version": "2.6.9", 2045 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 2046 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 2047 | "requires": { 2048 | "ms": "2.0.0" 2049 | } 2050 | }, 2051 | "ms": { 2052 | "version": "2.0.0", 2053 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 2054 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 2055 | } 2056 | } 2057 | }, 2058 | "serve-static": { 2059 | "version": "1.13.2", 2060 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", 2061 | "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", 2062 | "requires": { 2063 | "encodeurl": "~1.0.2", 2064 | "escape-html": "~1.0.3", 2065 | "parseurl": "~1.3.2", 2066 | "send": "0.16.2" 2067 | } 2068 | }, 2069 | "setimmediate": { 2070 | "version": "1.0.5", 2071 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", 2072 | "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" 2073 | }, 2074 | "setprototypeof": { 2075 | "version": "1.1.0", 2076 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", 2077 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" 2078 | }, 2079 | "seventh": { 2080 | "version": "0.7.18", 2081 | "resolved": "https://registry.npmjs.org/seventh/-/seventh-0.7.18.tgz", 2082 | "integrity": "sha512-fwO9/Ogh28KdAUz71fgJBn3NezuFWaiVLa2HW2/6TlAGsUzTUVPIuxQEGMKqPNerTJ+ZZDrFlPH98sdvBZpa1A==", 2083 | "requires": { 2084 | "setimmediate": "^1.0.5" 2085 | } 2086 | }, 2087 | "shebang-command": { 2088 | "version": "1.2.0", 2089 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 2090 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 2091 | "requires": { 2092 | "shebang-regex": "^1.0.0" 2093 | } 2094 | }, 2095 | "shebang-regex": { 2096 | "version": "1.0.0", 2097 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 2098 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" 2099 | }, 2100 | "signal-exit": { 2101 | "version": "3.0.2", 2102 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 2103 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 2104 | "dev": true 2105 | }, 2106 | "slice-ansi": { 2107 | "version": "1.0.0", 2108 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", 2109 | "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", 2110 | "dev": true, 2111 | "requires": { 2112 | "is-fullwidth-code-point": "^2.0.0" 2113 | } 2114 | }, 2115 | "sprintf-js": { 2116 | "version": "1.0.3", 2117 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 2118 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" 2119 | }, 2120 | "statuses": { 2121 | "version": "1.4.0", 2122 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 2123 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" 2124 | }, 2125 | "string-kit": { 2126 | "version": "0.9.1", 2127 | "resolved": "https://registry.npmjs.org/string-kit/-/string-kit-0.9.1.tgz", 2128 | "integrity": "sha512-2iWkq43jbvG7WSqei4iVlpjmA7JWgqIC4lHgpwib0687B2d3qUOQQeaVDjqyG4Epuxx/0NY87zOqOyIjZVKxVA==" 2129 | }, 2130 | "string-width": { 2131 | "version": "2.1.1", 2132 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 2133 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 2134 | "requires": { 2135 | "is-fullwidth-code-point": "^2.0.0", 2136 | "strip-ansi": "^4.0.0" 2137 | } 2138 | }, 2139 | "string_decoder": { 2140 | "version": "1.1.1", 2141 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 2142 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 2143 | "dev": true, 2144 | "requires": { 2145 | "safe-buffer": "~5.1.0" 2146 | } 2147 | }, 2148 | "strip-ansi": { 2149 | "version": "4.0.0", 2150 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 2151 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 2152 | "requires": { 2153 | "ansi-regex": "^3.0.0" 2154 | } 2155 | }, 2156 | "strip-json-comments": { 2157 | "version": "2.0.1", 2158 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 2159 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 2160 | "dev": true 2161 | }, 2162 | "subscriptions-transport-ws": { 2163 | "version": "0.9.16", 2164 | "resolved": "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.16.tgz", 2165 | "integrity": "sha512-pQdoU7nC+EpStXnCfh/+ho0zE0Z+ma+i7xvj7bkXKb1dvYHSZxgRPaU6spRP+Bjzow67c/rRDoix5RT0uU9omw==", 2166 | "requires": { 2167 | "backo2": "^1.0.2", 2168 | "eventemitter3": "^3.1.0", 2169 | "iterall": "^1.2.1", 2170 | "symbol-observable": "^1.0.4", 2171 | "ws": "^5.2.0" 2172 | }, 2173 | "dependencies": { 2174 | "iterall": { 2175 | "version": "1.2.2", 2176 | "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz", 2177 | "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==" 2178 | }, 2179 | "ws": { 2180 | "version": "5.2.2", 2181 | "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", 2182 | "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", 2183 | "requires": { 2184 | "async-limiter": "~1.0.0" 2185 | } 2186 | } 2187 | } 2188 | }, 2189 | "supports-color": { 2190 | "version": "5.5.0", 2191 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 2192 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 2193 | "requires": { 2194 | "has-flag": "^3.0.0" 2195 | } 2196 | }, 2197 | "supports-hyperlinks": { 2198 | "version": "1.0.1", 2199 | "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz", 2200 | "integrity": "sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==", 2201 | "requires": { 2202 | "has-flag": "^2.0.0", 2203 | "supports-color": "^5.0.0" 2204 | }, 2205 | "dependencies": { 2206 | "has-flag": { 2207 | "version": "2.0.0", 2208 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", 2209 | "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" 2210 | } 2211 | } 2212 | }, 2213 | "symbol-observable": { 2214 | "version": "1.2.0", 2215 | "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", 2216 | "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" 2217 | }, 2218 | "table": { 2219 | "version": "4.0.2", 2220 | "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", 2221 | "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", 2222 | "dev": true, 2223 | "requires": { 2224 | "ajv": "^5.2.3", 2225 | "ajv-keywords": "^2.1.0", 2226 | "chalk": "^2.1.0", 2227 | "lodash": "^4.17.4", 2228 | "slice-ansi": "1.0.0", 2229 | "string-width": "^2.1.1" 2230 | } 2231 | }, 2232 | "terminal-kit": { 2233 | "version": "1.27.0", 2234 | "resolved": "https://registry.npmjs.org/terminal-kit/-/terminal-kit-1.27.0.tgz", 2235 | "integrity": "sha512-vEKmPMaQKA/UadxjgJ99jxBGEiTcEzEG510cp2VXNgK63/h/zyS0hTQ4STPy87rsfh+n6PjEq4XbB/fdc9vgEQ==", 2236 | "requires": { 2237 | "@cronvel/get-pixels": "^3.3.1", 2238 | "lazyness": "^1.1.1", 2239 | "ndarray": "^1.0.18", 2240 | "nextgen-events": "^1.1.0", 2241 | "seventh": "^0.7.18", 2242 | "string-kit": "^0.9.0", 2243 | "tree-kit": "^0.6.0" 2244 | } 2245 | }, 2246 | "text-table": { 2247 | "version": "0.2.0", 2248 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 2249 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 2250 | "dev": true 2251 | }, 2252 | "through": { 2253 | "version": "2.3.8", 2254 | "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", 2255 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 2256 | "dev": true 2257 | }, 2258 | "tmp": { 2259 | "version": "0.0.33", 2260 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 2261 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 2262 | "dev": true, 2263 | "requires": { 2264 | "os-tmpdir": "~1.0.2" 2265 | } 2266 | }, 2267 | "tree-kit": { 2268 | "version": "0.6.1", 2269 | "resolved": "https://registry.npmjs.org/tree-kit/-/tree-kit-0.6.1.tgz", 2270 | "integrity": "sha512-7mV4KbsLMuA6ths3J1wpVUj2PLmLdoNEGnP9fm3kxef4UXYC/A0rL5gKsqtkUaCMuRYUMORyioy8IpBWUBQ1Ig==" 2271 | }, 2272 | "ts-invariant": { 2273 | "version": "0.2.1", 2274 | "resolved": "https://registry.npmjs.org/ts-invariant/-/ts-invariant-0.2.1.tgz", 2275 | "integrity": "sha512-Z/JSxzVmhTo50I+LKagEISFJW3pvPCqsMWLamCTX8Kr3N5aMrnGOqcflbe5hLUzwjvgPfnLzQtHZv0yWQ+FIHg==", 2276 | "requires": { 2277 | "tslib": "^1.9.3" 2278 | } 2279 | }, 2280 | "tslib": { 2281 | "version": "1.9.3", 2282 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", 2283 | "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" 2284 | }, 2285 | "type-check": { 2286 | "version": "0.3.2", 2287 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 2288 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 2289 | "dev": true, 2290 | "requires": { 2291 | "prelude-ls": "~1.1.2" 2292 | } 2293 | }, 2294 | "type-is": { 2295 | "version": "1.6.16", 2296 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", 2297 | "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", 2298 | "requires": { 2299 | "media-typer": "0.3.0", 2300 | "mime-types": "~2.1.18" 2301 | } 2302 | }, 2303 | "typedarray": { 2304 | "version": "0.0.6", 2305 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 2306 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", 2307 | "dev": true 2308 | }, 2309 | "uniq": { 2310 | "version": "1.0.1", 2311 | "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", 2312 | "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=" 2313 | }, 2314 | "universalify": { 2315 | "version": "0.1.2", 2316 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 2317 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" 2318 | }, 2319 | "unpipe": { 2320 | "version": "1.0.0", 2321 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 2322 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 2323 | }, 2324 | "util-deprecate": { 2325 | "version": "1.0.2", 2326 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 2327 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 2328 | "dev": true 2329 | }, 2330 | "utils-merge": { 2331 | "version": "1.0.1", 2332 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 2333 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 2334 | }, 2335 | "vary": { 2336 | "version": "1.1.2", 2337 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 2338 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 2339 | }, 2340 | "whatwg-fetch": { 2341 | "version": "2.0.4", 2342 | "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", 2343 | "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" 2344 | }, 2345 | "which": { 2346 | "version": "1.3.1", 2347 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 2348 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 2349 | "requires": { 2350 | "isexe": "^2.0.0" 2351 | } 2352 | }, 2353 | "widest-line": { 2354 | "version": "2.0.1", 2355 | "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", 2356 | "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", 2357 | "requires": { 2358 | "string-width": "^2.1.1" 2359 | } 2360 | }, 2361 | "wordwrap": { 2362 | "version": "1.0.0", 2363 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 2364 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", 2365 | "dev": true 2366 | }, 2367 | "wrap-ansi": { 2368 | "version": "3.0.1", 2369 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", 2370 | "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", 2371 | "requires": { 2372 | "string-width": "^2.1.1", 2373 | "strip-ansi": "^4.0.0" 2374 | } 2375 | }, 2376 | "wrappy": { 2377 | "version": "1.0.2", 2378 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2379 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 2380 | "dev": true 2381 | }, 2382 | "write": { 2383 | "version": "0.2.1", 2384 | "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", 2385 | "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", 2386 | "dev": true, 2387 | "requires": { 2388 | "mkdirp": "^0.5.1" 2389 | } 2390 | }, 2391 | "ws": { 2392 | "version": "6.2.0", 2393 | "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.0.tgz", 2394 | "integrity": "sha512-deZYUNlt2O4buFCa3t5bKLf8A7FPP/TVjwOeVNpw818Ma5nk4MLXls2eoEGS39o8119QIYxTrTDoPQ5B/gTD6w==", 2395 | "requires": { 2396 | "async-limiter": "~1.0.0" 2397 | } 2398 | }, 2399 | "yallist": { 2400 | "version": "2.1.2", 2401 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 2402 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", 2403 | "dev": true 2404 | }, 2405 | "zen-observable": { 2406 | "version": "0.8.13", 2407 | "resolved": "https://registry.npmjs.org/zen-observable/-/zen-observable-0.8.13.tgz", 2408 | "integrity": "sha512-fa+6aDUVvavYsefZw0zaZ/v3ckEtMgCFi30sn91SEZea4y/6jQp05E3omjkX91zV6RVdn15fqnFZ6RKjRGbp2g==" 2409 | }, 2410 | "zen-observable-ts": { 2411 | "version": "0.8.18", 2412 | "resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.18.tgz", 2413 | "integrity": "sha512-q7d05s75Rn1j39U5Oapg3HI2wzriVwERVo4N7uFGpIYuHB9ff02P/E92P9B8T7QVC93jCMHpbXH7X0eVR5LA7A==", 2414 | "requires": { 2415 | "tslib": "^1.9.3", 2416 | "zen-observable": "^0.8.0" 2417 | } 2418 | } 2419 | } 2420 | } 2421 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json2graphql", 3 | "description": "A CLI tool to import JSON data in Hasura GraphQL Engine", 4 | "version": "0.1.5", 5 | "author": "Hasura", 6 | "bin": { 7 | "json2graphql": "./bin/run", 8 | "j2g": "./bin/run" 9 | }, 10 | "bugs": "https://github.com/hasura/json2graphql/issues", 11 | "dependencies": { 12 | "@oclif/command": "1.4.35", 13 | "@oclif/config": "1.6.33", 14 | "@oclif/errors": "1.1.2", 15 | "@oclif/plugin-help": "2.0.5", 16 | "cli-ux": "4.7.3", 17 | "graphqurl": "^0.3.3", 18 | "moment": "2.22.2", 19 | "node-fetch": "2.2.0" 20 | }, 21 | "devDependencies": { 22 | "eslint": "4.19.1", 23 | "eslint-config-oclif": "1.5.1" 24 | }, 25 | "engines": { 26 | "node": ">=8.0.0" 27 | }, 28 | "files": [ 29 | "/bin", 30 | "/src" 31 | ], 32 | "homepage": "https://github.com/hasura/json2graphql", 33 | "keywords": [ 34 | "oclif", 35 | "cli", 36 | "graphql", 37 | "grapql-engine", 38 | "json", 39 | "mock" 40 | ], 41 | "license": "MIT", 42 | "main": "src/command.js", 43 | "oclif": { 44 | "bin": "json2graphql" 45 | }, 46 | "repository": "hasura/json2graphql", 47 | "scripts": { 48 | "eslint": "eslint .", 49 | "eslintfix": "eslint . --fix", 50 | "posttest": "npm run eslint", 51 | "test": "cd test && ./test.sh" 52 | }, 53 | "pre-commit": [ 54 | "eslintfix" 55 | ] 56 | } 57 | -------------------------------------------------------------------------------- /src/command.js: -------------------------------------------------------------------------------- 1 | const {Command, flags} = require('@oclif/command'); 2 | const fetch = require('node-fetch'); 3 | const {CLIError} = require('@oclif/errors'); 4 | const {cli} = require('cli-ux'); 5 | const importData = require('./import/import'); 6 | const resolve = require('path').resolve; 7 | 8 | class JSON2GraphQL extends Command { 9 | async run() { 10 | const {args, flags} = this.parse(JSON2GraphQL); 11 | const {url} = args; 12 | if (!url) { 13 | throw new CLIError('endpoint is required: \'json2graphql \''); 14 | } 15 | 16 | const {db, overwrite} = flags; 17 | const key = flags['access-key']; 18 | const secret = flags['admin-secret']; 19 | 20 | if (secret !== undefined && key !== undefined) { 21 | throw new CLIError('cannot use both flags "access-key" and "admin-secret"', 'use "admin-secret" for versions greater than v1.0.0-alpha37 and "access-key" otherwise'); 22 | } 23 | 24 | if (!url) { 25 | throw new CLIError('endpoint is required: \'json2graphql -d ./db.js\''); 26 | } 27 | const safeUrl = this.getSafeUrl(url); 28 | if (!db) { 29 | throw new CLIError('path to sample database is required: \'json2graphql -d ./db.js\''); 30 | } 31 | const dbJson = await this.getDbJson(db); 32 | const headers = { 33 | [secret ? 'x-hasura-admin-secret' : 'x-hasura-access-key']: secret || key, 34 | }; 35 | const urlVerification = await this.verifyUrl(safeUrl, headers); 36 | if (urlVerification.error) { 37 | throw new CLIError(urlVerification.message); 38 | } else { 39 | cli.action.stop('Done!'); 40 | await importData(dbJson, safeUrl, headers, overwrite); 41 | } 42 | } 43 | 44 | getDbJson(db) { 45 | const ret = require(resolve(db)); 46 | return typeof ret === 'function' ? ret() : ret; 47 | } 48 | 49 | getSafeUrl(url) { 50 | const urlLength = url.length; 51 | return url[urlLength - 1] === '/' ? url.slice(0, -1) : url; 52 | } 53 | 54 | async verifyUrl(url, headers) { 55 | try { 56 | cli.action.start('Verifying URL'); 57 | const resp = await fetch( 58 | `${url}/v1/version`, 59 | { 60 | method: 'GET', 61 | headers, 62 | } 63 | ); 64 | return resp.status === 200 ? {error: false} : {error: true, message: 'invalid admin-secret or access-key'}; 65 | } catch (e) { 66 | return {error: true, message: 'invalid URL'}; 67 | } 68 | } 69 | } 70 | 71 | JSON2GraphQL.description = `JSON Data Import: Import JSON data to Hasura GraphQL Engine 72 | # Examples: 73 | 74 | # Import data from a JSON file to Hasura GraphQL Engine without admin secret 75 | json2graphql https://hge.herokuapp.com --db=./path/to/db.js 76 | 77 | # Import data from a JSON file to Hasura GraphQL Engine with admin secret 78 | json2graphql https://hge.herokuapp.com --admin-secret='' --db=./path/to/db.js 79 | 80 | `; 81 | 82 | JSON2GraphQL.usage = 'URL [-k KEY]'; 83 | 84 | JSON2GraphQL.flags = { 85 | // add --version flag to show CLI version 86 | version: flags.version(), 87 | 88 | // add --help flag to show CLI version 89 | help: flags.help({char: 'h'}), 90 | 91 | // Admin secret to Hasura GraphQL Engine 92 | 'admin-secret': flags.string({ 93 | char: 's', 94 | description: 'Admin secret to Hasura GraphQL Engine (X-Hasura-Admin-Secret). Use the flag --access-key if GraphQL Engine version is older than v1.0.0-alpha38', 95 | }), 96 | 97 | // Access key to Hasura GraphQL Engine 98 | 'access-key': flags.string({ 99 | char: 'k', 100 | description: 'Access key to Hasura GraphQL Engine (X-Hasura-Access-Key). Use the flag --admin-secret if GraphQL Engine version is greater than v1.0.0-alpha37', 101 | }), 102 | 103 | db: flags.string({ 104 | char: 'd', 105 | description: 'Path to the .js files that exports a JSON database', 106 | }), 107 | 108 | overwrite: flags.boolean({ 109 | char: 'o', 110 | description: 'Overwrite tables if they exist', 111 | }), 112 | }; 113 | 114 | JSON2GraphQL.args = [ 115 | { 116 | name: 'url', 117 | description: 'URL where Hasura GraphQL Engine is running', 118 | }, 119 | ]; 120 | 121 | module.exports = JSON2GraphQL; 122 | -------------------------------------------------------------------------------- /src/import/check.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch'); 2 | const {cli} = require('cli-ux'); 3 | const throwError = require('./error'); 4 | 5 | const createTables = async (tables, url, headers, overwrite, runSql, sql) => { 6 | if (overwrite) { 7 | cli.action.stop('Skipped!'); 8 | cli.action.start('Creating tables'); 9 | await runSql(sql, url, headers); 10 | } else { 11 | try { 12 | const resp = await fetch( 13 | `${url}/v1/query`, 14 | { 15 | method: 'POST', 16 | headers, 17 | body: JSON.stringify({ 18 | type: 'run_sql', 19 | args: { 20 | sql: "select * from information_schema.tables where table_schema = 'public';", 21 | }, 22 | }), 23 | } 24 | ); 25 | const dbTables = await resp.json(); 26 | const tableIndex = dbTables.result[0].indexOf('table_name'); 27 | let found = false; 28 | for (let i = dbTables.result.length - 1; i > 0; i--) { 29 | if (tables.find(t => t.name === dbTables.result[i][tableIndex])) { 30 | found = true; 31 | throwError('Message: Your JSON database contains tables that already exist in Postgres public schema. Please use the flag "--overwrite" to overwrite them.'); 32 | } 33 | } 34 | if (!found) { 35 | cli.action.stop('Done!'); 36 | cli.action.start('Creating tables'); 37 | await runSql(sql, url, headers); 38 | } 39 | } catch (e) { 40 | console.log('Unexpected: ', e); 41 | process.exit(1); 42 | } 43 | } 44 | }; 45 | 46 | module.exports = { 47 | createTables, 48 | }; 49 | -------------------------------------------------------------------------------- /src/import/error.js: -------------------------------------------------------------------------------- 1 | const {cli} = require('cli-ux'); 2 | 3 | module.exports = message => { 4 | cli.action.stop('Error'); 5 | console.log(message); 6 | process.exit(1); 7 | }; 8 | -------------------------------------------------------------------------------- /src/import/generateTables.js: -------------------------------------------------------------------------------- 1 | const throwError = require('./error'); 2 | 3 | const getDataType = (data, column) => { 4 | if (typeof data === 'number') { 5 | return 'numeric'; 6 | } 7 | if (typeof data === 'string' || data === null) { 8 | return 'text'; 9 | } 10 | if (typeof data === 'boolean') { 11 | return 'boolean'; 12 | } 13 | if (data.constructor.name === 'Date') { 14 | return 'timestamptz'; 15 | } 16 | if (data.constructor.name === 'Object' || data.constructor.name === 'Array') { 17 | return 'jsonb'; 18 | } 19 | throwError(`message: invalid data type given for column ${column}: ${typeof data}`); 20 | }; 21 | 22 | const isForeign = (name, db) => { 23 | const l = name.length; 24 | if (l > 3) { 25 | if (name.substring(l - 3, l) === '_id' && 26 | Object.keys(db).find(tableName => { 27 | return tableName === name.substring(0, l - 3); 28 | })) { 29 | return true; 30 | } 31 | } 32 | return false; 33 | }; 34 | 35 | const getColumnData = (dataArray, db) => { 36 | let refColumns = {}; 37 | dataArray.forEach(row => { 38 | refColumns = { 39 | ...refColumns, 40 | ...row, 41 | }; 42 | }); 43 | const columnData = []; 44 | Object.keys(refColumns).forEach(column => { 45 | const columnMetadata = {}; 46 | if (!column) { 47 | throwError("message: column names can't be empty strings"); 48 | } 49 | columnMetadata.name = column; 50 | const sampleData = refColumns[column]; 51 | columnMetadata.type = getDataType(sampleData, column, db); 52 | columnMetadata.isForeign = isForeign(column, db); 53 | columnData.push(columnMetadata); 54 | }); 55 | return columnData; 56 | }; 57 | 58 | const hasPrimaryKey = dataObj => { 59 | let has = true; 60 | dataObj.forEach(obj => { 61 | if (!Object.keys(obj).find(name => name === 'id')) { 62 | has = false; 63 | } 64 | }); 65 | return has; 66 | }; 67 | 68 | const sanitizeData = db => { 69 | const newDb = {}; 70 | for (var tableName in db) { 71 | const newTableName = tableName.replace(/[^a-zA-Z0-9]/g, '_').replace(' ', '_'); 72 | newDb[newTableName] = []; 73 | for (var i = db[tableName].length - 1; i >= 0; i--) { 74 | const data = db[tableName][i]; 75 | const newData = {}; 76 | for (var key in data) { 77 | const newKey = key.replace(/[^a-zA-Z0-9]/g, '_').replace(' ', '_'); 78 | newData[newKey] = data[key]; 79 | } 80 | newDb[tableName].push(newData); 81 | } 82 | } 83 | return newDb; 84 | }; 85 | 86 | const generate = db => { 87 | const metaData = []; 88 | Object.keys(db).forEach(rootField => { 89 | const tableMetadata = {}; 90 | if (!hasPrimaryKey(db[rootField], rootField)) { 91 | throwError(`message: a unique column with name "id" must present in table "${rootField}"`); 92 | } 93 | tableMetadata.name = rootField; 94 | tableMetadata.columns = getColumnData(db[rootField], db); 95 | tableMetadata.dependencies = []; 96 | tableMetadata.columns.forEach(column => { 97 | if (column.isForeign) { 98 | tableMetadata.dependencies.push(column.name.substring(0, column.name.length - 3)); 99 | } 100 | }); 101 | metaData.push(tableMetadata); 102 | }); 103 | return metaData; 104 | }; 105 | 106 | module.exports = { 107 | generate, 108 | sanitizeData, 109 | }; 110 | -------------------------------------------------------------------------------- /src/import/import.js: -------------------------------------------------------------------------------- 1 | const {generate, sanitizeData} = require('./generateTables'); 2 | const {generateSql, runSql} = require('./sql'); 3 | const {cli} = require('cli-ux'); 4 | const {trackTables} = require('./track'); 5 | const {getInsertOrder, insertData} = require('./insert'); 6 | const {createRelationships} = require('./relationships'); 7 | const {createTables} = require('./check'); 8 | 9 | const importData = async (jsonDb, url, headers, overwrite) => { 10 | cli.action.start('Processing JSON data'); 11 | const db = sanitizeData(jsonDb); 12 | const tables = generate(db); 13 | const sql = generateSql(tables); 14 | cli.action.stop('Done!'); 15 | cli.action.start('Checking database'); 16 | createTables(tables, url, headers, overwrite, runSql, sql).then(() => { 17 | cli.action.stop('Done!'); 18 | cli.action.start('Tracking tables'); 19 | trackTables(tables, url, headers).then(() => { 20 | cli.action.stop('Done!'); 21 | cli.action.start('Creating relationships'); 22 | createRelationships(tables, url, headers).then(() => { 23 | cli.action.stop('Done!'); 24 | cli.action.start('Inserting data'); 25 | const insertOrder = getInsertOrder(tables); 26 | insertData(insertOrder, db, tables, url, headers); 27 | }); 28 | }); 29 | }); 30 | }; 31 | 32 | module.exports = importData; 33 | -------------------------------------------------------------------------------- /src/import/insert.js: -------------------------------------------------------------------------------- 1 | const {query} = require('graphqurl'); 2 | const moment = require('moment'); 3 | const {cli} = require('cli-ux'); 4 | const throwError = require('./error'); 5 | 6 | const getInsertOrder = tables => { 7 | let order = []; 8 | const tablesHash = {}; 9 | tables.forEach(table => { 10 | tablesHash[table.name] = table; 11 | }); 12 | const pushedHash = {}; 13 | const setOrder = table => { 14 | if (table.dependencies.length === 0) { 15 | order.push(table.name); 16 | pushedHash[table.name] = true; 17 | } else { 18 | table.dependencies.forEach(parentTable => { 19 | if (!pushedHash[parentTable] && parentTable !== table.name) { 20 | setOrder(tablesHash[parentTable]); 21 | } 22 | }); 23 | order.push(table.name); 24 | pushedHash[table.name] = true; 25 | } 26 | }; 27 | 28 | tables.forEach(table => { 29 | if (!pushedHash[table.name]) { 30 | setOrder(table); 31 | } 32 | }); 33 | return order; 34 | }; 35 | 36 | const transformData = (data, tables) => { 37 | const newData = {}; 38 | tables.forEach(table => { 39 | const tableData = data[table.name]; 40 | newData[table.name] = []; 41 | tableData.forEach(row => { 42 | const newRow = {...row}; 43 | table.columns.forEach(column => { 44 | if (column.type === 'timestamptz' && row[column.name]) { 45 | newRow[column.name] = moment(row[column.name]).format(); 46 | } 47 | if (column.type === 'jsonb' && row[column.name]) { 48 | newRow[column.name] = JSON.stringify(row[column.name]); 49 | } 50 | }); 51 | newData[table.name].push(newRow); 52 | }); 53 | }); 54 | return newData; 55 | }; 56 | 57 | const insertData = async (insertOrder, sampleData, tables, url, headers) => { 58 | const transformedData = transformData(sampleData, tables); 59 | let mutationString = ''; 60 | let objectString = ''; 61 | const variables = {}; 62 | insertOrder.forEach(tableName => { 63 | mutationString += `insert_${tableName} ( objects: $objects_${tableName} ) { affected_rows } \n`; 64 | objectString += `$objects_${tableName}: [${tableName}_insert_input!]!,\n`; 65 | variables[`objects_${tableName}`] = transformedData[tableName]; 66 | }); 67 | const mutation = `mutation ( ${objectString} ) { ${mutationString} }`; 68 | cli.action.start('Inserting data'); 69 | try { 70 | const response = await query({ 71 | query: mutation, 72 | endpoint: `${url}/v1/graphql`, 73 | variables, 74 | headers, 75 | }); 76 | if (response.data !== null && response.data !== 'undefined') { 77 | cli.action.stop('Done!'); 78 | } else { 79 | throw new Error(response); 80 | } 81 | } catch (e) { 82 | throwError(JSON.stringify(e, null, 2)); 83 | } 84 | }; 85 | 86 | module.exports = { 87 | getInsertOrder, 88 | insertData, 89 | }; 90 | -------------------------------------------------------------------------------- /src/import/relationships.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch'); 2 | const throwError = require('./error'); 3 | 4 | const getObjRelationshipName = dep => { 5 | const relName = `${dep}By${dep[0].toUpperCase()}`; 6 | return dep.length === 1 ? relName + 'Id' : relName + dep.substring(1, dep.length) + 'Id'; 7 | }; 8 | 9 | const getArrayRelationshipName = (table, parent) => { 10 | const relName = `${table}sBy${parent[0].toUpperCase()}`; 11 | return parent.length === 1 ? `${relName}Id` : `${relName}${parent.substring(1, parent.length)}Id`; 12 | }; 13 | 14 | const generateRelationships = tables => { 15 | const objectRelationships = []; 16 | const arrayRelationships = []; 17 | tables.forEach(table => { 18 | if (table.dependencies.length > 0) { 19 | table.dependencies.forEach(dep => { 20 | objectRelationships.push({ 21 | type: 'create_object_relationship', 22 | args: { 23 | table: table.name, 24 | name: `${getObjRelationshipName(dep)}`, 25 | using: { 26 | foreign_key_constraint_on: `${dep}_id`, 27 | }, 28 | }, 29 | }); 30 | arrayRelationships.push({ 31 | type: 'create_array_relationship', 32 | args: { 33 | table: dep, 34 | name: `${getArrayRelationshipName(table.name, dep)}`, 35 | using: { 36 | foreign_key_constraint_on: { 37 | table: table.name, 38 | column: `${dep}_id`, 39 | }, 40 | }, 41 | }, 42 | }); 43 | }); 44 | } 45 | }); 46 | return { 47 | objectRelationships, 48 | arrayRelationships, 49 | }; 50 | }; 51 | 52 | const createRelationships = async (tables, url, headers) => { 53 | const relationships = generateRelationships(tables); 54 | const bulkQuery = { 55 | type: 'bulk', 56 | args: [], 57 | }; 58 | relationships.objectRelationships.forEach(or => bulkQuery.args.push(or)); 59 | relationships.arrayRelationships.forEach(ar => bulkQuery.args.push(ar)); 60 | const resp = await fetch( 61 | `${url}/v1/query`, 62 | { 63 | method: 'POST', 64 | body: JSON.stringify(bulkQuery), 65 | headers, 66 | } 67 | ); 68 | if (resp.status !== 200) { 69 | const error = await resp.json(); 70 | throwError(JSON.stringify(error, null, 2)); 71 | } 72 | }; 73 | 74 | module.exports = { 75 | createRelationships, 76 | }; 77 | -------------------------------------------------------------------------------- /src/import/sql.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch'); 2 | const throwError = require('./error'); 3 | 4 | const runSql = async (sqlArray, url, headers) => { 5 | let sqlString = ''; 6 | sqlArray.forEach(sql => { 7 | sqlString += sql; 8 | }); 9 | const resp = await fetch( 10 | `${url}/v1/query`, 11 | { 12 | method: 'POST', 13 | body: JSON.stringify({ 14 | type: 'run_sql', 15 | args: { 16 | sql: sqlString, 17 | cascade: true, 18 | }, 19 | }), 20 | headers, 21 | } 22 | ); 23 | if (resp.status !== 200) { 24 | const error = await resp.json(); 25 | throwError(JSON.stringify(error, null, 2)); 26 | } 27 | }; 28 | 29 | const generateCreateTableSql = metadata => { 30 | const sqlArray = []; 31 | metadata.forEach(table => { 32 | sqlArray.push(`drop table if exists public."${table.name}" cascade;`); 33 | let columnSql = '('; 34 | table.columns.forEach((column, i) => { 35 | if (column.name === 'id') { 36 | columnSql += `"id" ${column.type} not null primary key`; 37 | } else { 38 | columnSql += `"${column.name}" ${column.type}`; 39 | } 40 | columnSql += (table.columns.length === i + 1) ? ' ) ' : ', '; 41 | }); 42 | const createTableSql = `create table public."${table.name}" ${columnSql};`; 43 | sqlArray.push(createTableSql); 44 | }); 45 | return sqlArray; 46 | }; 47 | 48 | const generateConstraintsSql = metadata => { 49 | const sqlArray = []; 50 | metadata.forEach(table => { 51 | table.columns.forEach(column => { 52 | if (column.isForeign) { 53 | const fkSql = `add foreign key ("${column.name}") references public."${column.name.substring(0, column.name.length - 3)}" ("id");`; 54 | sqlArray.push(`alter table public."${table.name}" ${fkSql}`); 55 | } 56 | }); 57 | }); 58 | return sqlArray; 59 | }; 60 | 61 | const generateSql = metadata => { 62 | const createTableSql = generateCreateTableSql(metadata); 63 | const constraintsSql = generateConstraintsSql(metadata); 64 | let sqlArray = [...createTableSql, ...constraintsSql]; 65 | return sqlArray; 66 | }; 67 | 68 | module.exports = { 69 | generateSql, 70 | runSql, 71 | }; 72 | -------------------------------------------------------------------------------- /src/import/track.js: -------------------------------------------------------------------------------- 1 | const fetch = require('node-fetch'); 2 | const throwError = require('./error'); 3 | 4 | const trackTables = async (tables, url, headers) => { 5 | const bulkQueryArgs = []; 6 | tables.forEach(table => { 7 | bulkQueryArgs.push({ 8 | type: 'add_existing_table_or_view', 9 | args: { 10 | name: table.name, 11 | schema: 'public', 12 | }, 13 | }); 14 | }); 15 | const bulkQuery = { 16 | type: 'bulk', 17 | args: bulkQueryArgs, 18 | }; 19 | const resp = await fetch( 20 | `${url}/v1/query`, 21 | { 22 | method: 'POST', 23 | body: JSON.stringify(bulkQuery), 24 | headers, 25 | } 26 | ); 27 | if (resp.status !== 200) { 28 | const error = await resp.json(); 29 | throwError(JSON.stringify(error, null, 2)); 30 | } 31 | }; 32 | 33 | module.exports = { 34 | trackTables, 35 | }; 36 | -------------------------------------------------------------------------------- /test/db.js: -------------------------------------------------------------------------------- 1 | const db = { 2 | j2g_test_users: [ 3 | {id: 1, name: 'Fredi Bach', country: 'CH', birthday: '1975-09-03', sex: 'm', email: 'osxcode@gmail.com', j2g_test_userStatus_id: 2, date: new Date(), object: {hey: 'there', whats: 'up'}}, 4 | {id: 2, name: 'Samuel Patzen', country: 'CH', birthday: '1978-02-01', sex: 'm', email: 'patzen@bluewin.ch', j2g_test_userStatus_id: 2, date: new Date()}, 5 | {id: 3, name: 'Hans Muster', country: 'CH', birthday: '1978-02-01', sex: 'm', email: 'hans.muster@domain.ch', j2g_test_userStatus_id: 1, date: new Date()}, 6 | ], 7 | j2g_test_userStatus: [ 8 | {id: 1, key: 'inactive'}, 9 | {id: 2, key: 'active'}, 10 | {id: 3, key: 'blocked'}, 11 | ], 12 | j2g_test_userConfigs: [ 13 | {id: 1, j2g_test_users_id: 1}, 14 | ], 15 | j2g_test_leagues: [ 16 | {id: 1, name: 'Switzerland', yearly: true, description: 'Waypoint are all placed in Switzerland by local instructors and top pilots.', created: '2018-05-01', seasonStart: '10-01', seasonEnd: '09-31'}, 17 | {id: 2, name: 'Austria', yearly: true, description: 'Waypoint are all placed in Austria by local instructors and top pilots.', created: '2018-05-02', seasonStart: '10-01', seasonEnd: '09-31'}, 18 | {id: 3, name: 'Vol Liber Grischun Clubmeisterschaft', yearly: false, created: '2018-05-02', seasonStart: '2018-10-01', seasonEnd: '2048-10-01'}, 19 | ], 20 | j2g_test_userLeagues: [ 21 | {id: 1, j2g_test_users_id: 1, j2g_test_leagues_id: 1, isAdmin: true}, 22 | {id: 2, j2g_test_users_id: 1, j2g_test_leagues_id: 2, isAdmin: true}, 23 | {id: 3, j2g_test_users_id: 2, j2g_test_leagues_id: 1}, 24 | {id: 4, j2g_test_users_id: 1, j2g_test_leagues_id: 3}, 25 | {id: 5, j2g_test_users_id: 2, j2g_test_leagues_id: 3, isAdmin: true}, 26 | ], 27 | j2g_test_files: [ 28 | {id: 1, j2g_test_mimetypes_id: 1, width: 250, height: 250, url: 'https://imgplaceholder.com/250x250/cccccc/757575/ion-happy-outline'}, 29 | {id: 2, j2g_test_mimetypes_id: 1, width: 800, height: 400, url: 'https://imgplaceholder.com/800x400/cccccc/757575/fa-image'}, 30 | {id: 3, j2g_test_mimetypes_id: 1, width: 300, height: 200, url: 'https://imgplaceholder.com/300x200/cccccc/757575/fa-map-marker'}, 31 | {id: 4, j2g_test_mimetypes_id: 3, url: 'https://mycdn.com/fredi-bach/2018-07-02-001.igc'}, 32 | {id: 5, j2g_test_mimetypes_id: 3, url: 'https://mycdn.com/fredi-bach/2018-07-03-001.igc'}, 33 | ], 34 | j2g_test_mimetypes: [ 35 | {id: 1, mime: 'image/png', description: 'Portable Network Graphics'}, 36 | {id: 2, mime: 'image/jpeg', description: 'JPEG images'}, 37 | {id: 3, mime: 'application/vnd.fai.igc', description: 'Flight track file'}, 38 | ], 39 | j2g_test_types: [ 40 | {id: 1, name: 'Challenge', description: 'A challenging waypoint, only for the best', points: 200}, 41 | {id: 2, name: 'Altitude', description: 'A big mountain, that needs altitude to reach', points: 150}, 42 | {id: 3, name: 'Beauty', description: 'Just a nice view', points: 100}, 43 | {id: 4, name: 'Takeoff', description: 'Official takoeff', points: 10}, 44 | {id: 5, name: 'Landing', description: 'Official landing', points: 10}, 45 | ], 46 | j2g_test_waypoints: [ 47 | {id: 1, j2g_test_leagues_id: 1, j2g_test_types_id: 1, lat: 3.789, lng: 41.987, radius: 400, points: 100, minAltitude: 3500, name: 'Oberalp Pass', description: 'From Andermatt to Disentis', j2g_test_files_id: 3}, 48 | {id: 2, j2g_test_leagues_id: 1, j2g_test_types_id: 2, lat: 3.589, lng: 41.787, radius: 400, points: 100, minAltitude: 3500, name: 'Furka Pass', description: 'From the Goms to Andermatt', j2g_test_files_id: 3}, 49 | {id: 3, j2g_test_leagues_id: 1, j2g_test_types_id: 4, lat: 3.889, lng: 40.787, radius: 400, points: 10, name: 'Fiesch'}, 50 | ], 51 | j2g_test_waypointNotes: [ 52 | {id: 1, j2g_test_waypoints_id: 1, j2g_test_noteTypes_id: 1, title: 'Föhn', text: 'Bei Föhn sehr gefährlich!'}, 53 | {id: 2, j2g_test_waypoints_id: 1, j2g_test_noteTypes_id: 2, title: 'Basis', text: 'Braucht mindestens 3000 Meter Basis, besser mehr.'}, 54 | ], 55 | j2g_test_waypointPhotos: [ 56 | {id: 1, j2g_test_users_id: 1, official: true, j2g_test_waypoints_id: 1, j2g_test_mimetypes_id: 2, width: 1080, height: 960, url: 'https://mycdn.com/fredi-bach/oberalp-2018-1.jpeg'}, 57 | {id: 2, j2g_test_users_id: 1, official: true, j2g_test_waypoints_id: 1, j2g_test_mimetypes_id: 2, width: 1080, height: 960, url: 'https://mycdn.com/fredi-bach/oberalp-2018-2.jpeg'}, 58 | {id: 3, j2g_test_users_id: 2, official: false, j2g_test_waypoints_id: 1, j2g_test_mimetypes_id: 2, width: 1080, height: 960, url: 'https://mycdn.com/fredi-bach/oberalp-2018-3.jpeg'}, 59 | ], 60 | j2g_test_waypointSuggestions: [ 61 | {id: 1, j2g_test_users_id: 2, j2g_test_leagues_id: 1, j2g_test_types_id: 1, lat: 11.789, lng: 33.987, radius: 800, points: 100, minAltitude: 3500, name: 'Limmeren Stausee', description: 'Auf dem Weg von der Surselva ins Glaernerland', files_id: 3}, 62 | ], 63 | j2g_test_noteTypes: [ 64 | {id: 1, name: 'Wind', icon: 'wind', class: 'waypoint-note-wind'}, 65 | {id: 2, name: 'Altitude', icon: 'altitude', class: 'waypoint-note-altitude'}, 66 | ], 67 | j2g_test_sponsors: [ 68 | {id: 1, waypoints_id: 1, j2g_test_users_id: 1, name: 'Flugschule Appenzell', url: 'http://www.gleitschirm.ch', slogan: 'Die Flugschule im Alpstein.'}, 69 | {id: 2, waypoints_id: 2, name: 'Ozone', url: 'http://www.flyozone.ch', slogan: 'Real world performance.'}, 70 | ], 71 | j2g_test_waypointChats: [ 72 | {id: 1, j2g_test_waypoints_id: 1, j2g_test_users_id: 1, message: 'Can be quite hard with low base!', datetime: '2018-07-02 12:48:45'}, 73 | {id: 2, j2g_test_waypoints_id: 1, j2g_test_users_id: 2, message: 'Oh yes, it can!', datetime: '2018-07-02 12:52:11'}, 74 | ], 75 | j2g_test_wings: [ 76 | {id: 1, model: 'Zeno', brand: 'Ozone', certification: 'D'}, 77 | {id: 2, model: 'Mentor 3', brand: 'Nova', certification: 'B'}, 78 | ], 79 | j2g_test_flights: [ 80 | {id: 1, j2g_test_users_id: 1, j2g_test_leagues_id: 1, j2g_test_wings_id: 1, date: '2018-07-02', score: 200, j2g_test_files_id: 4, comment: 'Bockig!'}, 81 | {id: 2, j2g_test_users_id: 2, j2g_test_leagues_id: 1, j2g_test_wings_id: 2, date: '2018-07-03', score: 100, j2g_test_files_id: 5}, 82 | ], 83 | j2g_test_favoriteFlights: [ 84 | {id: 1, j2g_test_users_id: 1, j2g_test_flights_id: 2, datetime: '2018-07-02 12:48:45'}, 85 | ], 86 | j2g_test_flightWaypoints: [ 87 | {id: 1, j2g_test_flights_id: 1, j2g_test_waypoints_id: 1, datetime: '2018-07-02 12:48:45', score: 100}, 88 | {id: 2, j2g_test_flights_id: 1, j2g_test_waypoints_id: 2, datetime: '2018-07-02 13:11:59', score: 100}, 89 | {id: 3, j2g_test_flights_id: 2, j2g_test_waypoints_id: 2, datetime: '2018-08-02 14:06:11', score: 100}, 90 | ], 91 | j2g_test_flightComments: [ 92 | {id: 1, j2g_test_flights_id: 1, j2g_test_users_id: 2, datetime: '2018-08-02 14:06:11', text: 'Ok, that was nice!'}, 93 | {id: 2, j2g_test_flights_id: 1, j2g_test_users_id: 1, datetime: '2018-08-02 14:09:11', text: 'Thanks'}, 94 | ], 95 | j2g_test_leagueSeasonUserScores: [ 96 | {id: 1, j2g_test_users_id: 1, j2g_test_leagues_id: 1, season: '2018', score: 200, flightCount: 1}, 97 | {id: 2, j2g_test_users_id: 1, j2g_test_leagues_id: 2, season: '2018', score: 0, flightCount: 0}, 98 | {id: 3, j2g_test_users_id: 2, j2g_test_leagues_id: 1, season: '2018', score: 100, flightCount: 1}, 99 | ], 100 | j2g_test_routes: [ 101 | {id: 1, j2g_test_users_id: 1, j2g_test_leagues_id: 1, name: 'Wallis Sightseeing', description: 'A great route for a low wind high cloudbase day.'}, 102 | {id: 2, j2g_test_users_id: 1, j2g_test_leagues_id: 1, name: 'Surselva Adventure'}, 103 | ], 104 | j2g_test_routeWaypoints: [ 105 | {id: 1, j2g_test_routes_id: 1, j2g_test_waypoints_id: 1}, 106 | {id: 2, j2g_test_routes_id: 1, j2g_test_waypoints_id: 2, j2g_test_routeWaypoints_id: 1}, 107 | {id: 3, j2g_test_routes_id: 1, j2g_test_waypoints_id: 3, j2g_test_routeWaypoints_id: 2}, 108 | ], 109 | j2g_test_favoriteRoutes: [ 110 | {id: 1, j2g_test_users_id: 1, j2g_test_routes_id: 1, datetime: '2018-07-01 15:48:45'}, 111 | ], 112 | }; 113 | 114 | module.exports = db; 115 | -------------------------------------------------------------------------------- /test/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ -z "$TEST_HGE_URL" ] && [ -z "$TEST_X_HASURA_ADMIN_SECRET" ]; then 3 | echo "ERROR: Please run the test command with the environment variable TEST_HGE_URL" 4 | else 5 | ../bin/run $TEST_HGE_URL --admin-secret=$TEST_X_HASURA_ADMIN_SECRET --db=./db.js --overwrite && node verify.js 6 | fi 7 | -------------------------------------------------------------------------------- /test/verify.js: -------------------------------------------------------------------------------- 1 | const {query} = require('graphqurl'); 2 | const fetch = require('node-fetch'); 3 | 4 | const complexQuery = ` 5 | query { 6 | j2g_test_favoriteRoutes { 7 | j2g_test_routesByJ2g_test_routesId { 8 | j2g_test_leaguesByJ2g_test_leaguesId { 9 | j2g_test_flightssByJ2g_test_leaguesId ( 10 | order_by: { 11 | id:asc 12 | } 13 | ){ 14 | j2g_test_flightCommentssByJ2g_test_flightsId(order_by: {j2g_test_users_id:asc}) { 15 | j2g_test_users_id 16 | j2g_test_usersByJ2g_test_usersId { 17 | email 18 | } 19 | } 20 | } 21 | } 22 | } 23 | } 24 | } 25 | `; 26 | 27 | const testTables = [ 28 | 'j2g_test_favoriteFlights', 29 | 'j2g_test_favoriteRoutes', 30 | 'j2g_test_files', 31 | 'j2g_test_flightComments', 32 | 'j2g_test_flightWaypoints', 33 | 'j2g_test_flights', 34 | 'j2g_test_leagueSeasonUserScores', 35 | 'j2g_test_leagues', 36 | 'j2g_test_mimetypes', 37 | 'j2g_test_noteTypes', 38 | 'j2g_test_routeWaypoints', 39 | 'j2g_test_routes', 40 | 'j2g_test_sponsors', 41 | 'j2g_test_types', 42 | 'j2g_test_userConfigs', 43 | 'j2g_test_userLeagues', 44 | 'j2g_test_userStatus', 45 | 'j2g_test_users', 46 | 'j2g_test_waypointChats', 47 | 'j2g_test_waypointNotes', 48 | 'j2g_test_waypointPhotos', 49 | 'j2g_test_waypointSuggestions', 50 | 'j2g_test_waypoints', 51 | 'j2g_test_wings', 52 | ]; 53 | 54 | const deleteTables = () => { 55 | const deleteQuery = { 56 | type: 'bulk', 57 | args: testTables.map(tname => ({ 58 | type: 'run_sql', 59 | args: { 60 | sql: `drop table if exists public."${tname}" cascade;`, 61 | cascade: true, 62 | }, 63 | })), 64 | }; 65 | fetch( 66 | `${process.env.TEST_HGE_URL}/v1/query`, 67 | { 68 | method: 'POST', 69 | headers: {'x-hasura-admin-secret': process.env.TEST_X_HASURA_ADMIN_SECRET}, 70 | body: JSON.stringify(deleteQuery), 71 | } 72 | ).then(() => { 73 | console.log('Test tables deleted!'); 74 | }).catch(() => console.log('Failed deleting test tables')); 75 | }; 76 | 77 | const verifyDataImport = () => { 78 | let resp = null; 79 | return query({ 80 | query: complexQuery, 81 | endpoint: `${process.env.TEST_HGE_URL}/v1/graphql`, 82 | headers: {'x-hasura-admin-secret': process.env.TEST_X_HASURA_ADMIN_SECRET}, 83 | }).then(response => { 84 | resp = response; 85 | if (response.data.j2g_test_favoriteRoutes[0] 86 | .j2g_test_routesByJ2g_test_routesId 87 | .j2g_test_leaguesByJ2g_test_leaguesId 88 | .j2g_test_flightssByJ2g_test_leaguesId[0] 89 | .j2g_test_flightCommentssByJ2g_test_flightsId[0] 90 | .j2g_test_usersByJ2g_test_usersId.email === 'osxcode@gmail.com') { 91 | console.log('✔︎ Test passed'); 92 | } else { 93 | console.log('✖ Test failed. Unexpected response.'); 94 | console.log(response.data); 95 | } 96 | }).catch(() => { 97 | console.log('✖ Test failed. Unexpected response.'); 98 | console.log(JSON.stringify(resp, null, 2)); 99 | }); 100 | }; 101 | verifyDataImport().then(() => deleteTables()).catch(() => deleteTables()); 102 | --------------------------------------------------------------------------------