Full Code of graphql/graphql-playground for AI

main 91ed7d8b1c1b cached
316 files
869.0 KB
246.0k tokens
609 symbols
1 requests
Download .txt
Showing preview only (956K chars total). Download the full file or copy to clipboard to get everything.
Repository: graphql/graphql-playground
Branch: main
Commit: 91ed7d8b1c1b
Files: 316
Total size: 869.0 KB

Directory structure:
gitextract_3l4bavka/

├── .dependabot/
│   └── config.yml
├── .github/
│   ├── CONTRIBUTING.md
│   ├── ISSUE_TEMPLATE.md
│   └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .nvmrc
├── .vscode/
│   └── settings.json
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── SECURITY.md
├── docs/
│   └── security/
│       ├── 2020-xss-template-injection.md
│       └── 2021-schema-xss-phishing-attack.md
├── lerna.json
├── package.json
├── packages/
│   ├── graphql-playground-electron/
│   │   ├── .babelrc
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── main/
│   │   │   │   ├── createWindow.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── menu.ts
│   │   │   │   ├── notify.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── updates.ts
│   │   │   ├── renderer/
│   │   │   │   ├── components/
│   │   │   │   │   ├── App.tsx
│   │   │   │   │   ├── InitialView/
│   │   │   │   │   │   ├── InitialView.tsx
│   │   │   │   │   │   ├── Toggle.tsx
│   │   │   │   │   │   └── data.ts
│   │   │   │   │   ├── Loading.tsx
│   │   │   │   │   └── Root.tsx
│   │   │   │   ├── index.css
│   │   │   │   ├── index.html
│   │   │   │   ├── index.tsx
│   │   │   │   ├── redux/
│   │   │   │   │   ├── actions/
│   │   │   │   │   │   └── history.ts
│   │   │   │   │   ├── createStore.ts
│   │   │   │   │   └── reducers/
│   │   │   │   │       ├── history.ts
│   │   │   │   │       └── index.ts
│   │   │   │   └── utils/
│   │   │   │       └── errify.ts
│   │   │   └── shared/
│   │   │       └── utils.ts
│   │   ├── static/
│   │   │   └── icons/
│   │   │       └── icon.icns
│   │   ├── tsconfig.json
│   │   ├── tslint.json
│   │   ├── typings/
│   │   │   ├── custom.d.ts
│   │   │   └── styled-jsx.d.ts
│   │   ├── webpack.config.build.js
│   │   └── webpack.config.js
│   ├── graphql-playground-html/
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── examples/
│   │   │   └── xss-attack/
│   │   │       ├── README.md
│   │   │       ├── index.js
│   │   │       └── package.json
│   │   ├── minimal.html
│   │   ├── minimalWithoutCDN.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── get-loading-markup.ts
│   │   │   ├── index.ts
│   │   │   └── render-playground-page.ts
│   │   ├── tsconfig.json
│   │   └── withAnimation.html
│   ├── graphql-playground-middleware-express/
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── examples/
│   │   │   ├── basic/
│   │   │   │   ├── .envrc
│   │   │   │   ├── .graphqlconfig.yml
│   │   │   │   ├── README.md
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   └── graphcool/
│   │   │       ├── .envrc
│   │   │       ├── .graphqlconfig.yml
│   │   │       ├── README.md
│   │   │       ├── datamodel.graphql
│   │   │       ├── graphcool.yml
│   │   │       ├── index.js
│   │   │       ├── package.json
│   │   │       ├── prisma.yml
│   │   │       └── schema.graphql
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── graphql-playground-middleware-hapi/
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── examples/
│   │   │   └── basic/
│   │   │       ├── README.md
│   │   │       ├── index.js
│   │   │       └── package.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── graphql-playground-middleware-koa/
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── examples/
│   │   │   └── basic/
│   │   │       ├── .graphqlconfig.yml
│   │   │       ├── README.md
│   │   │       ├── index.js
│   │   │       └── package.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── graphql-playground-middleware-lambda/
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── examples/
│   │   │   └── basic/
│   │   │       ├── .gitignore
│   │   │       ├── README.md
│   │   │       ├── handler.js
│   │   │       ├── package.json
│   │   │       └── serverless.yml
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   └── graphql-playground-react/
│       ├── .babelrc
│       ├── .gitignore
│       ├── CHANGELOG.md
│       ├── LICENSE
│       ├── README.md
│       ├── config/
│       │   ├── env.js
│       │   ├── jest/
│       │   │   ├── cssTransform.js
│       │   │   ├── fileTransform.js
│       │   │   └── typescriptTransform.js
│       │   ├── paths.js
│       │   ├── polyfills.js
│       │   ├── webpack.config.dev.js
│       │   ├── webpack.config.prod.js
│       │   └── webpackDevServer.config.js
│       ├── jest.config.js
│       ├── package.json
│       ├── public/
│       │   ├── _headers
│       │   ├── _redirects
│       │   ├── affiliates.graphql
│       │   ├── auth.graphql
│       │   ├── blogging.graphql
│       │   ├── chat.graphql
│       │   ├── conferences.graphql
│       │   ├── empty.graphql
│       │   ├── freecom.graphql
│       │   ├── hn-relay-full.graphql
│       │   ├── hn-relay.graphql
│       │   ├── hn-starter.graphql
│       │   ├── hn.graphql
│       │   ├── index.html
│       │   ├── insta-auth0.graphql
│       │   ├── insta-email.graphql
│       │   ├── insta-expo-auth.graphql
│       │   ├── insta-files.graphql
│       │   ├── instagram-full.graphql
│       │   ├── instagram.graphql
│       │   ├── movies-import.graphql
│       │   ├── pokedex.graphql
│       │   ├── simple-pokedex.graphql
│       │   ├── todo.graphql
│       │   ├── twitter.graphql
│       │   ├── welcome-rp.graphql
│       │   ├── welcome.graphql
│       │   └── worldchat.graphql
│       ├── release.sh
│       ├── scripts/
│       │   ├── build.js
│       │   ├── start.js
│       │   └── test.js
│       ├── src/
│       │   ├── __snapshots__/
│       │   │   └── index.test.tsx.snap
│       │   ├── components/
│       │   │   ├── Button.tsx
│       │   │   ├── Copy.tsx
│       │   │   ├── EndpointPopup.tsx
│       │   │   ├── FileEditor.tsx
│       │   │   ├── GraphQLBinApp.tsx
│       │   │   ├── HistoryPopup/
│       │   │   │   ├── HistoryChooser.tsx
│       │   │   │   ├── HistoryHeader.tsx
│       │   │   │   └── HistoryItems.tsx
│       │   │   ├── HistoryPopup.tsx
│       │   │   ├── Icons/
│       │   │   │   └── index.tsx
│       │   │   ├── MiddlewareApp.tsx
│       │   │   ├── Modal.tsx
│       │   │   ├── Playground/
│       │   │   │   ├── ConfigEditor.tsx
│       │   │   │   ├── DocExplorer/
│       │   │   │   │   ├── Argument.tsx
│       │   │   │   │   ├── ArgumentInline.tsx
│       │   │   │   │   ├── ColumnDoc.tsx
│       │   │   │   │   ├── DocTypeSchema.tsx
│       │   │   │   │   ├── DocsStyles.tsx
│       │   │   │   │   ├── DocsTypes/
│       │   │   │   │   │   ├── DocType.tsx
│       │   │   │   │   │   ├── EnumTypeSchema.tsx
│       │   │   │   │   │   ├── ScalarType.tsx
│       │   │   │   │   │   └── UnionTypeSchema.tsx
│       │   │   │   │   ├── ErrorContainer.tsx
│       │   │   │   │   ├── FieldDoc.tsx
│       │   │   │   │   ├── GraphDocs.tsx
│       │   │   │   │   ├── GraphDocsRoot.tsx
│       │   │   │   │   ├── RootColumn.tsx
│       │   │   │   │   ├── SchemaDoc.tsx
│       │   │   │   │   ├── SearchBox.tsx
│       │   │   │   │   ├── SearchResults.tsx
│       │   │   │   │   └── TypeLink.tsx
│       │   │   │   ├── EditorWrapper.tsx
│       │   │   │   ├── ExecuteButton.tsx
│       │   │   │   ├── ExecuteButtonOperation.tsx
│       │   │   │   ├── ExplorerTabs/
│       │   │   │   │   ├── SideTab.tsx
│       │   │   │   │   └── SideTabs.tsx
│       │   │   │   ├── GraphQLEditor.tsx
│       │   │   │   ├── QueryEditor.tsx
│       │   │   │   ├── ResponseTracing.tsx
│       │   │   │   ├── ResultViewer.tsx
│       │   │   │   ├── Results.tsx
│       │   │   │   ├── SchemaExplorer/
│       │   │   │   │   ├── SDLEditor.tsx
│       │   │   │   │   ├── SDLHeader.tsx
│       │   │   │   │   ├── SDLTypes/
│       │   │   │   │   │   ├── SDLDocType.tsx
│       │   │   │   │   │   ├── SDLFieldDoc.tsx
│       │   │   │   │   │   ├── SDLStyles.tsx
│       │   │   │   │   │   ├── SDLType.tsx
│       │   │   │   │   │   └── SDLUnionType.tsx
│       │   │   │   │   └── SDLView.tsx
│       │   │   │   ├── SchemaFetcher.ts
│       │   │   │   ├── Tab.tsx
│       │   │   │   ├── TabBar.tsx
│       │   │   │   ├── TopBar/
│       │   │   │   │   ├── Polling.tsx
│       │   │   │   │   ├── PollingIcon.tsx
│       │   │   │   │   ├── Positioner.tsx
│       │   │   │   │   ├── Reload.tsx
│       │   │   │   │   ├── ReloadIcon.tsx
│       │   │   │   │   ├── SchemaReload.tsx
│       │   │   │   │   └── TopBar.tsx
│       │   │   │   ├── TracingRow.tsx
│       │   │   │   ├── VariableEditor.tsx
│       │   │   │   ├── onHasCompletion.tsx
│       │   │   │   └── util/
│       │   │   │       ├── InvalidSchemaError.ts
│       │   │   │       ├── NoSchemaError.ts
│       │   │   │       ├── ageOfDate.ts
│       │   │   │       ├── createSDL.ts
│       │   │   │       ├── fibonacci-backoff.ts
│       │   │   │       ├── getQueryFacts.ts
│       │   │   │       ├── getQueryTypes.ts
│       │   │   │       ├── getSelectedOperationName.ts
│       │   │   │       ├── getWorkspaceId.ts
│       │   │   │       ├── hasSubscription.ts
│       │   │   │       ├── immutableMemoize.ts
│       │   │   │       ├── makeOperation.ts
│       │   │   │       ├── parseHeaders.ts
│       │   │   │       ├── session.ts
│       │   │   │       ├── shallowEqual.ts
│       │   │   │       ├── shouldUpdate.ts
│       │   │   │       ├── stack.ts
│       │   │   │       ├── toJS.tsx
│       │   │   │       └── whatChanged.ts
│       │   │   ├── Playground.tsx
│       │   │   ├── PlaygroundWrapper.tsx
│       │   │   ├── Popup.tsx
│       │   │   ├── ProjectsSideNav.tsx
│       │   │   ├── ProjectsSideNavItem.tsx
│       │   │   ├── Root.tsx
│       │   │   ├── Settings.tsx
│       │   │   ├── SettingsEditor.tsx
│       │   │   ├── Share.tsx
│       │   │   ├── Spinner.tsx
│       │   │   ├── Toggle.tsx
│       │   │   ├── ToggleButton.tsx
│       │   │   ├── Tooltip.tsx
│       │   │   ├── asyncComponent.tsx
│       │   │   ├── resolveRefStrings.ts
│       │   │   └── util.ts
│       │   ├── constants.ts
│       │   ├── fixtures/
│       │   │   ├── exampleSchema.ts
│       │   │   └── sdl.ts
│       │   ├── graphqlConfig.ts
│       │   ├── index.css
│       │   ├── index.test.tsx
│       │   ├── index.tsx
│       │   ├── lib.tsx
│       │   ├── localDevIndex.tsx
│       │   ├── middlewareIndex.tsx
│       │   ├── setupEnzyme.ts
│       │   ├── state/
│       │   │   ├── appHistory/
│       │   │   │   ├── actions.ts
│       │   │   │   └── reducers.ts
│       │   │   ├── createStore.ts
│       │   │   ├── docs/
│       │   │   │   ├── actions.ts
│       │   │   │   ├── reducers.ts
│       │   │   │   └── selectors.ts
│       │   │   ├── general/
│       │   │   │   ├── actions.ts
│       │   │   │   ├── reducers.ts
│       │   │   │   └── selectors.ts
│       │   │   ├── history/
│       │   │   │   ├── actions.ts
│       │   │   │   ├── reducers.ts
│       │   │   │   └── selectors.ts
│       │   │   ├── localStorage.ts
│       │   │   ├── rootSaga.ts
│       │   │   ├── sessions/
│       │   │   │   ├── WebSocketLink.ts
│       │   │   │   ├── actions.ts
│       │   │   │   ├── fetchingSagas.ts
│       │   │   │   ├── reducers.ts
│       │   │   │   ├── sagas.ts
│       │   │   │   └── selectors.ts
│       │   │   ├── sharing/
│       │   │   │   ├── actions.ts
│       │   │   │   ├── reducers.ts
│       │   │   │   ├── selectors.ts
│       │   │   │   └── sharingSaga.ts
│       │   │   └── workspace/
│       │   │       ├── actions.ts
│       │   │       ├── deserialize.ts
│       │   │       └── reducers.ts
│       │   ├── styled/
│       │   │   ├── index.ts
│       │   │   ├── styled.ts
│       │   │   └── theme.ts
│       │   ├── types.ts
│       │   ├── utils/
│       │   │   └── performance.ts
│       │   └── utils.ts
│       ├── tests/
│       │   └── schema.faker.graphql
│       ├── tsconfig.build.json
│       ├── tsconfig.jest.json
│       ├── tsconfig.json
│       ├── tslint.json
│       └── typings/
│           ├── custom.d.ts
│           └── styled-jsx.d.ts
├── renovate.json
└── scripts/
    ├── build.sh
    ├── release-html.sh
    ├── release-react.sh
    └── versions.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .dependabot/config.yml
================================================
version: 1
update_configs:
  - package_manager: 'javascript'
    directory: '/'
    update_schedule: 'live'
    allowed_updates:
      - match:
          update_type: 'security'
    commit_message:
      prefix: 'fix'
      prefix_development: 'chore'
      include_scope: true
  - package_manager: 'javascript'
    directory: '/packages/graphql-playground-react'
    update_schedule: 'live'
    allowed_updates:
      - match:
          update_type: 'security'
    commit_message:
      prefix: 'fix'
      prefix_development: 'chore'
      include_scope: true
  - package_manager: 'javascript'
    directory: '/packages/graphql-playground-html'
    update_schedule: 'live'
    allowed_updates:
      - match:
          update_type: 'security'
    commit_message:
      prefix: 'fix'
      prefix_development: 'chore'
      include_scope: true
  - package_manager: 'javascript'
    directory: '/packages/graphql-playground-electron'
    update_schedule: 'live'
    allowed_updates:
      - match:
          update_type: 'security'
    commit_message:
      prefix: 'fix'
      prefix_development: 'fix'
      include_scope: true
  - package_manager: 'javascript'
    directory: '/packages/graphql-playground-middleware-hapi'
    update_schedule: 'live'
    allowed_updates:
      - match:
          update_type: 'security'
    commit_message:
      prefix: 'fix'
      prefix_development: 'fix'
      include_scope: true
  - package_manager: 'javascript'
    directory: '/packages/graphql-playground-middleware-express'
    update_schedule: 'live'
    allowed_updates:
      - match:
          update_type: 'security'
    commit_message:
      prefix: 'fix'
      prefix_development: 'fix'
      include_scope: true
  - package_manager: 'javascript'
    directory: '/packages/graphql-playground-middleware-koa'
    update_schedule: 'live'
    allowed_updates:
      - match:
          update_type: 'security'
    commit_message:
      prefix: 'fix'
      prefix_development: 'fix'
      include_scope: true
  - package_manager: 'javascript'
    directory: '/packages/graphql-playground-middleware-lambda'
    update_schedule: 'live'
    allowed_updates:
      - match:
          update_type: 'security'
    commit_message:
      prefix: 'fix'
      prefix_development: 'fix'
      include_scope: true
  - package_manager: 'javascript'
    directory: '/packages/graphql-playground-middleware-hapi/examples/basic'
    update_schedule: 'live'
    allowed_updates:
      - match:
          update_type: 'security'
    commit_message:
      prefix: 'fix'
      prefix_development: 'fix'
      include_scope: true
  - package_manager: 'javascript'
    directory: '/packages/graphql-playground-middleware-express/examples/basic'
    update_schedule: 'live'
    allowed_updates:
      - match:
          update_type: 'security'
    commit_message:
      prefix: 'fix'
      prefix_development: 'fix'
      include_scope: true
  - package_manager: 'javascript'
    directory: '/packages/graphql-playground-middleware-express/examples/graphcool'
    update_schedule: 'live'
    allowed_updates:
      - match:
          update_type: 'security'
    commit_message:
      prefix: 'fix'
      prefix_development: 'fix'
      include_scope: true
  - package_manager: 'javascript'
    directory: '/packages/graphql-playground-middleware-lambda/examples/basic'
    update_schedule: 'live'
    allowed_updates:
      - match:
          update_type: 'security'
    commit_message:
      prefix: 'fix'
      prefix_development: 'fix'
      include_scope: true
  - package_manager: 'javascript'
    directory: '/packages/graphql-playground-middleware-koa/examples/basic'
    update_schedule: 'live'
    allowed_updates:
      - match:
          update_type: 'security'
    commit_message:
      prefix: 'fix'
      prefix_development: 'fix'
      include_scope: true


================================================
FILE: .github/CONTRIBUTING.md
================================================
# Contributing to this project

[fork]: https://github.com/graphcool/graphql-playground/fork
[pr]: https://github.com/graphcool/graphql-playground/compare
[code-of-conduct]: ../CODE_OF_CONDUCT.md

Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great.

Please note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project you agree to abide by its terms.

## Contribution Agreement

As a contributor, you represent that the code you submit is your original work or that of your employer (in which case you represent you have the right to bind your employer). By submitting code, you (and, if applicable, your employer) are licensing the submitted code to the open source community subject to the MIT license.


## Submitting a pull request

0. [Fork][fork] and clone the repository
0. Create a new branch: `git checkout -b feature/my-new-feature-name`
0. Run `npm install` or `yarn install` to make sure you've got the latest dependencies.
0. Make your change
0. Run the unit tests and make sure they pass and have 100% coverage. (`npm test`)
0. Push to your fork and [submit a pull request][pr]
0. Pat your self on the back and wait for your pull request to be reviewed and merged.

Here are a few things you can do that will increase the likelihood of your pull request being accepted:

- Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests.
- Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
- In your pull request description, provide as much detail as possible. This context helps the reviewer to understand the motivation for and impact of the change.
- Make sure that all the unit tests still pass. PRs with failing tests won't be merged.

## Resources

- [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
- [Contributing to Open Source on GitHub](https://guides.github.com/activities/contributing-to-open-source/)
- [Using Pull Requests](https://help.github.com/articles/about-pull-requests/)
- [GitHub Help](https://help.github.com)


================================================
FILE: .github/ISSUE_TEMPLATE.md
================================================
#### This issue pertains to the following package(s):

- [ ] GraphQL Playground - Electron App
- [ ] GraphQL Playground HTML
- [ ] GraphQL Playground
- [ ] GraphQL Playground Express Middleware
- [ ] GraphQL Playground Hapi Middleware
- [ ] GraphQL Playground Koa Middleware
- [ ] GraphQL Playground Lambda Middleware

#### What OS and OS version are you experiencing the issue(s) on?


#### What version of graphql-playground(-electron/-middleware) are you experiencing the issue(s) on?


#### What is the expected behavior?


#### What is the actual behavior?


#### What steps may we take to reproduce the behavior?


_Please provide a gif or image of the issue for a quicker response/fix._


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
Fixes #.

Changes proposed in this pull request:

- 

- 

- 


================================================
FILE: .gitignore
================================================
# See http://help.github.com/ignore-files/ for more about ignoring files.

# dependencies
node_modules
example/node_modules
example/yarn.lock

# testing
/coverage

# production
/build

# misc
.DS_Store
.env
npm-debug.log
.idea
lib
/middleware
playground.css
*.log
**/examples/*/yarn.lock


================================================
FILE: .nvmrc
================================================
lts/dubnium


================================================
FILE: .vscode/settings.json
================================================
{
  "prettier.singleQuote": true,
  "prettier.trailingComma": "all",
  "prettier.semi": false,
}


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@graph.cool. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]

[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2017 Graphcool

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
<p align="center"><img src="https://imgur.com/5fzMbyV.png" width="269"></p>

[![npm version](https://badge.fury.io/js/graphql-playground-react.svg)](https://badge.fury.io/js/graphql-playground-react)
[![graphql](https://circleci.com/gh/graphql/graphql-playground.svg?style=shield)](https://circleci.com/gh/graphql/graphql-playground)

> **SECURITY WARNING:** both `graphql-playground-html` and [all four (4) of it's middleware dependents](#impacted-packages) until `graphql-playground-html@1.6.22` were subject to an  **XSS Reflection attack vulnerability only to unsanitized user input strings** to the functions therein. This was resolved in `graphql-playground-html@^1.6.22`. [More Information](#security-details) [CVE-2020-4038](https://github.com/graphql/graphql-playground/security/advisories/GHSA-4852-vrh7-28rf)


**Future of this repository**: See [this issue](https://github.com/graphql/graphql-playground/issues/1366#issuecomment-1062088978) for details.

---

GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration). <br />

[![](https://i.imgur.com/AE5W6OW.png)](https://graphqlbin.com/v2/6RQ6TM)

## Installation

```sh
$ brew install --cask graphql-playground
```

## Features

- ✨ Context-aware autocompletion & error highlighting
- 📚 Interactive, multi-column docs (keyboard support)
- ⚡️ Supports real-time GraphQL Subscriptions
- ⚙ GraphQL Config support with multiple Projects & Endpoints
- 🚥 Apollo Tracing support

## Security Details
> **NOTE: only _unsanitized user input_ to the functions in these packages is vulnerable** to the recently reported XSS Reflection attack.

### Impact

> Impacted are any and all unsanitized **user-defined** input to:
-`renderPlaygroundPage()`
-`koaPlayground()`
-`expressPlayground()`
-`koaPlayground()`
-`lambdaPlayground()

>  If you used static values, such as `graphql-playground-electron` does in [it's webpack config](https://github.com/prisma-labs/graphql-playground/blob/main/packages/graphql-playground-electron/webpack.config.build.js#L16), as well as the most common middleware implementations out there, they were not vulnerable to the attack.

The only reason this vulnerability exists is because we are using template strings in `renderPlaygroundPage()` with potentially unsanitized user defined variables. This allows an attacker to inject html and javascript into the page. 
- [Read more about preventing XSS in react](https://pragmaticwebsecurity.com/files/cheatsheets/reactxss.pdf)

Common examples may be user-defined path parameters, query string, unsanitized UI provided values in database, etc., that are used to build template strings or passed directly to a `renderPlaygroundPage()` or the matching middleware function equivalent listed above.

### Impacted Packages

**All versions of these packages are impacted until the ones specified below**, which are now safe for user defined input:

- `graphql-playground-html`: **☔ safe** @ `1.6.22`
- `graphql-playground-express` **☔ safe** @ `1.7.16`
- `graphql-playground-koa` **☔ safe** @ `1.6.15`
- `graphql-playground-hapi` **☔ safe** @ `1.6.13`
- `graphql-playground-lambda` **☔ safe** @ `1.7.17`
- `graphql-playground-electron` has always been **☔ safe** from XSS attacks! This is because configuration is statically defined [it's webpack config](https://github.com/prisma-labs/graphql-playground/blob/main/packages/graphql-playground-electron/webpack.config.build.js#L16)
- `graphql-playground-react` is safe because it does not use `renderPlaygroundPage()` anywhere, and thus is not susceptible to template string XSS reflection attacks.

### More Information

See the [security docs](./SECURITY.md) for more details on how your implementation might be impacted by this vulnerability. It contains safe examples, unsafe examples, workarounds, and more details.

We've also provided ['an example of the xss using the express middleware]('https://github.com/prisma-labs/graphql-playground/tree/main/packages/graphql-playground-html/examples/xss-attack')

## FAQ

### How is this different from [GraphiQL](https://github.com/graphql/graphiql)?

GraphQL Playground uses components of GraphiQL under the hood but is meant as a more powerful GraphQL IDE enabling better (local) development workflows. Compared to GraphiQL, the GraphQL Playground ships with the following additional features:

- Interactive, multi-column schema documentation
- Automatic schema reloading
- Support for GraphQL Subscriptions
- Query history
- Configuration of HTTP headers
- Tabs

See the following question for more additonal features.

### What's the difference between the desktop app and the web version?

The desktop app is the same as the web version but includes these additional features:

- Partial support for [graphql-config](https://github.com/prismagraphql/graphql-config) enabling features like multi-environment setups (no support for sending HTTP headers).
- Double click on `*.graphql` files.

### How does GraphQL Bin work?

You can easily share your Playgrounds with others by clicking on the "Share" button and sharing the generated link. You can think about GraphQL Bin like Pastebin for your GraphQL queries including the context (endpoint, HTTP headers, open tabs etc).

<a href="https://graphqlbin.com/OksD" target="_blank">
 <img src="https://camo.githubusercontent.com/daf8c64dbde3097fdbe782c0645552550d530a73/68747470733a2f2f696d6775722e636f6d2f48316e36346c4c2e706e67" alt="" data-canonical-src="https://imgur.com/H1n64lL.png" style="max-width:100%;">
</a>

> You can also find the announcement blog post [here](https://blog.graph.cool/introducing-graphql-playground-f1e0a018f05d).

## Settings

In the top right corner of the Playground window you can click on the settings icon.
These are the settings currently available:

```js
{
  'editor.cursorShape': 'line', // possible values: 'line', 'block', 'underline'
  'editor.fontFamily': `'Source Code Pro', 'Consolas', 'Inconsolata', 'Droid Sans Mono', 'Monaco', monospace`,
  'editor.fontSize': 14,
  'editor.reuseHeaders': true, // new tab reuses headers from last tab
  'editor.theme': 'dark', // possible values: 'dark', 'light'
  'general.betaUpdates': false,
  'prettier.printWidth': 80,
  'prettier.tabWidth': 2,
  'prettier.useTabs': false,
  'request.credentials': 'omit', // possible values: 'omit', 'include', 'same-origin'
  'schema.polling.enable': true, // enables automatic schema polling
  'schema.polling.endpointFilter': '*localhost*', // endpoint filter for schema polling
  'schema.polling.interval': 2000, // schema polling interval in ms
  'schema.disableComments': boolean,
  'tracing.hideTracingResponse': true,
  'tracing.tracingSupported': true, // set false to remove x-apollo-tracing header from Schema fetch requests
}
```

## Usage

### Properties

The React component `<Playground />` and all middlewares expose the following options:

- `props` (Middlewares & React Component)
  - `endpoint` [`string`](optional) - the GraphQL endpoint url.
  - `subscriptionEndpoint` [`string`](optional) - the GraphQL subscriptions endpoint url.
  - `workspaceName` [`string`](optional) - in case you provide a GraphQL Config, you can name your workspace here
  - `config` [`string`](optional) - the JSON of a GraphQL Config. See an example [here](https://github.com/prismagraphql/graphql-playground/blob/main/packages/graphql-playground-react/src/localDevIndex.tsx#L47)
  - `settings` [`ISettings`](optional) - Editor settings in json format as [described here](https://github.com/prismagraphql/graphql-playground#settings)

```ts
interface ISettings {
  'editor.cursorShape': 'line' | 'block' | 'underline'
  'editor.fontFamily': string
  'editor.fontSize': number
  'editor.reuseHeaders': boolean
  'editor.theme': 'dark' | 'light'
  'general.betaUpdates': boolean
  'prettier.printWidth': number
  'prettier.tabWidth': number
  'prettier.useTabs': boolean
  'request.credentials': 'omit' | 'include' | 'same-origin'
  'request.globalHeaders': { [key: string]: string }
  'schema.polling.enable': boolean
  'schema.polling.endpointFilter': string
  'schema.polling.interval': number
  'schema.disableComments': boolean
  'tracing.hideTracingResponse': boolean
  'tracing.tracingSupported': boolean
}
```

- `schema` [`IntrospectionResult`](optional) - The result of an introspection query (an object of this form: `{__schema: {...}}`) The playground automatically fetches the schema from the endpoint. This is only needed when you want to override the schema.
- `tabs` [`Tab[]`](optional) - An array of tabs to inject. **Note: When using this feature, tabs will be resetted each time the page is reloaded**

```ts
interface Tab {
  endpoint: string
  query: string
  name?: string
  variables?: string
  responses?: string[]
  headers?: { [key: string]: string }
}
```

In addition to this, the React app provides some more properties:

- `props` (React Component)
- `createApolloLink` [`(session: Session, subscriptionEndpoint?: string) => ApolloLink`] - this is the equivalent to the `fetcher` of GraphiQL. For each query that is being executed, this function will be called

`createApolloLink` is only available in the React Component and not the middlewares, because the content must be serializable as it is being printed into a HTML template.

### As HTML Page

If you simply want to render the Playground HTML on your own, for example when implementing a GraphQL Server, there are 2 options for you:

1.  [The bare minimum HTML needed to render the Playground](https://github.com/prismagraphql/graphql-playground/blob/main/packages/graphql-playground-html/minimal.html)
2.  [The Playground HTML with full loading animation](https://github.com/prismagraphql/graphql-playground/blob/main/packages/graphql-playground-html/withAnimation.html)

Note: In case you do not want to serve assets from a CDN (like jsDelivr) and instead use a local copy, you will need to install `graphql-playground-react` from npm, and then replace all instances of `//cdn.jsdelivr.net/npm` with `./node_modules`. An example can be found [here](https://github.com/prismagraphql/graphql-playground/blob/main/packages/graphql-playground-html/minimalWithoutCDN.html)

### As React Component

#### Install

```sh
yarn add graphql-playground-react
```

#### Use

GraphQL Playground provides a React component responsible for rendering the UI and Session management.
There are **3 dependencies** needed in order to run the `graphql-playground-react` React component.

1.  _Open Sans_ and _Source Code Pro_ fonts
2.  Rendering the `<Playground />` component

The GraphQL Playground requires **React 16**.

Including Fonts (`1.`)

```html
<link
  href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700|Source+Code+Pro:400,700"
  rel="stylesheet"
/>
```

Including stylesheet and the component (`2., 3.`)

```js
import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { Playground, store } from 'graphql-playground-react'

ReactDOM.render(
  <Provider store={store}>
    <Playground endpoint='https://api.graph.cool/simple/v1/swapi' />
  </Provider>,
  document.body,
)
```

### As Server Middleware

#### Install

```sh
# Pick the one that matches your server framework
yarn add graphql-playground-middleware-express  # for Express or Connect
yarn add graphql-playground-middleware-hapi
yarn add graphql-playground-middleware-koa
yarn add graphql-playground-middleware-lambda
```

#### Usage with example

We have a full example for each of the frameworks below:

- **Express:** See [packages/graphql-playground-middleware-express/examples/basic](https://github.com/prismagraphql/graphql-playground/tree/main/packages/graphql-playground-middleware-express/examples/basic)

- **Hapi:** See [packages/graphql-playground-middleware-hapi](https://github.com/prismagraphql/graphql-playground/tree/main/packages/graphql-playground-middleware-hapi)

- **Koa:** See [packages/graphql-playground-middleware-koa](https://github.com/prismagraphql/graphql-playground/tree/main/packages/graphql-playground-middleware-koa)

- **Lambda (as serverless handler):** See [serverless-graphql-apollo](https://github.com/serverless/serverless-graphql-apollo) or a quick example below.

### As serverless handler

#### Install

```sh
yarn add graphql-playground-middleware-lambda
```

#### Usage

`handler.js`

```js
import lambdaPlayground from 'graphql-playground-middleware-lambda'
// or using require()
// const lambdaPlayground = require('graphql-playground-middleware-lambda').default

exports.graphqlHandler = function graphqlHandler(event, context, callback) {
  function callbackFilter(error, output) {
    // eslint-disable-next-line no-param-reassign
    output.headers['Access-Control-Allow-Origin'] = '*'
    callback(error, output)
  }

  const handler = graphqlLambda({ schema: myGraphQLSchema })
  return handler(event, context, callbackFilter)
}

exports.playgroundHandler = lambdaPlayground({
  endpoint: '/dev/graphql',
})
```

`serverless.yml`

```yaml
functions:
  graphql:
    handler: handler.graphqlHandler
    events:
      - http:
          path: graphql
          method: post
          cors: true
  playground:
    handler: handler.playgroundHandler
    events:
      - http:
          path: playground
          method: get
          cors: true
```

#### Security Issue

There is an [XSS Reflection Vulnerability](./SECURITY.md) when using these middlewares with unsanitized user input before

## Development

```sh
$ cd packages/graphql-playground-react
$ yarn
$ yarn start
```

Open
[localhost:3000/localDev.html?endpoint=https://api.graph.cool/simple/v1/swapi](http://localhost:3000/localDev.html?endpoint=https://api.graph.cool/simple/v1/swapi) for local development!

### Contributing to this project

This repository is managed by EasyCLA. Project participants must sign the free ([GraphQL Specification Membership agreement](https://preview-spec-membership.graphql.org) before making a contribution. You only need to do this one time, and it can be signed by [individual contributors](http://individual-spec-membership.graphql.org/) or their [employers](http://corporate-spec-membership.graphql.org/).

To initiate the signature process please open a PR against this repo. The EasyCLA bot will block the merge if we still need a membership agreement from you.

You can find [detailed information here](https://github.com/graphql/graphql-wg/tree/main/membership). If you have issues, please email [operations@graphql.org](mailto:operations@graphql.org).

If your company benefits from GraphQL and you would like to provide essential financial support for the systems and people that power our community, please also consider membership in the [GraphQL Foundation](https://foundation.graphql.org/join).

## Custom Theme

From `graphql-playground-react@1.7.0` on you can provide a `codeTheme` property to the React Component to customize your color theme.
These are the available options:

```ts
export interface EditorColours {
  property: string
  comment: string
  punctuation: string
  keyword: string
  def: string
  qualifier: string
  attribute: string
  number: string
  string: string
  builtin: string
  string2: string
  variable: string
  meta: string
  atom: string
  ws: string
  selection: string
  cursorColor: string
  editorBackground: string
  resultBackground: string
  leftDrawerBackground: string
  rightDrawerBackground: string
}
```

### Versions

This is repository is a "mono repo" and contains multiple packages using [Yarn workspaces](https://yarnpkg.com/lang/en/docs/workspaces/). Please be aware that versions are **not** synchronised between packages. The versions of the [release page](https://github.com/graphcool/graphql-playground/releases) refer to the electron app.

### Packages

In the folder `packages` you'll find the following packages:

- `graphql-playground-electron`: Cross-platform electron app which uses `graphql-playground-react`
- `graphql-playground-html`: Simple HTML page rendering a version of `graphql-playground-react` hosted on JSDeliver
- `graphql-playground-middleware-express`: Express middleware using `graphql-playground-html`
- `graphql-playground-middleware-hapi`: Hapi middleware using `graphql-playground-html`
- `graphql-playground-middleware-koa`: Koa middleware using `graphql-playground-html`
- `graphql-playground-middleware-lambda`: AWS Lambda middleware using `graphql-playground-html`
- `graphql-playground-react`: Core of GraphQL Playground built with ReactJS

<a name="help-and-community" />

## Help & Community [![Discord](https://img.shields.io/discord/586999333447270440.svg)](https://discord.gg/EXUYPaY)

Join our [Discord Server](https://discord.gg/EXUYPaY) if you run into issues or have questions. We love talking to you!

<p align="center"><a href="https://oss.prisma.io"><img src="https://imgur.com/IMU2ERq.png" alt="Prisma" height="170px"></a></p>


================================================
FILE: SECURITY.md
================================================
# Known Vulnerabilities

- [2021: Introspection Schema Phishing Attack XSS Vulnerability](docs/security/2021-schema-xss-phishing-attack.md)
- [2020: XSS Reflection Vulnerability](docs/security/2020-xss-template-injection.md)


================================================
FILE: docs/security/2020-xss-template-injection.md
================================================
## XSS Reflection Vulnerability

the origin of the vulnerability is in `renderPlaygroundPage`, found in `graphql-playground-html`

### Impact

When using

- `renderPlaygroundPage()`,
- `koaPlayground()`
- `expressPlayground()`
- `koaPlayground()`
- `lambdaPlayground()`
- any downstream dependent packages that use these functions

without sanitization of user input, your application is vulnerable to an XSS Reflection Attack. This is a serious vulnerability that could allow for exfiltration of data or user credentials, or to disrupt systems.

We've provided ['an example of the xss using the express middleware]('https://github.com/prisma-labs/graphql-playground/tree/main/packages/graphql-playground-middleware-express/examples/xss-attack')

### Impacted Packages

**All versions of these packages are impacted until those specified below**, which are now safe for user defined input:

- `graphql-playground-html`: **☔ safe** @ `1.6.22`
- `graphql-playground-express` **☔ safe** @ `1.7.16`
- `graphql-playground-koa` **☔ safe** @ `1.6.15`
- `graphql-playground-hapi` **☔ safe** @ `1.6.13`
- `graphql-playground-lambda` **☔ safe** @ `1.7.17`

### Static input was always safe

These examples are safe for _all versions_ **because input is static**

with `express` and `renderPlaygroundPage`:

```js
app.get('/playground', (req) => {
  res.html(
    renderPlaygroundPage({
      endpoint: `/our/graphql`,
    }),
  )
  next()
})
```

with `expressPlayground`:

```js
// params
app.get('/playground', (req) =>
  expressPlayground({
    endpoint: `/our/graphql`,
    settings: { 'editor.theme': req.query.darkMode ? 'dark' : 'light' },
  }),
)
```

with `koaPlayground`:

```js
const koa = require('koa')
const koaRouter = require('koa-router')
const koaPlayground = require('graphql-playground-middleware-koa')

const app = new koa()
const router = new koaRouter()

router.all('/playground', koaPlayground({ endpoint: '/graphql' }))
```

### Vulnerable Examples

Here are some examples where the vulnerability would be present before the patch, because of unfiltered user input

```js
const express = require('express')
const expressPlayground = require('graphql-playground-middleware-express')
  .default

const app = express()

app.use(express.json())

// params
app.get('/playground/:id', (req) =>
  expressPlayground({
    endpoint: `/our/graphql/${req.params.id}`,
  }),
)

// params
app.get('/playground', (req) =>
  expressPlayground({
    endpoint: `/our/graphql`,
    // any settings that are unsanitized user input, not just `endpoint`
    settings: { 'editor.fontFamily': req.query.font },
  }),
)
```

[See a proof of concept](packages/graphql-playground-html/examples/xss-attack) to understand the vulnerability better

### Workaround

To fix this issue without the update, you can sanitize however you want.

We suggest using [`xss`](https://www.npmjs.com/package/xss) (what we use for our own fix)

For example, with `graphql-playground-middleware-express`:

```js
const express = require('express')
const { filterXSS } = require('xss')
const expressPlayground = require('graphql-playground-middleware-express')
  .default


const app = express()

const filter = (val) => filterXSS(val, {
  whitelist: [],
  stripIgnoreTag: true,
  stripIgnoreTagBody: ['script']
})

// simple example
app.get('/playground/:id', (req) =>
  expressPlayground({ endpoint: `/graphql/${filter(req.params.id)}` })

// advanced params
app.get('/playground', (req) =>
  expressPlayground(JSON.parse(filter(JSON.stringify(req.query))))
```

[See a proof of concept workaround](packages/graphql-playground-html/examples/xss-attack), example #3


================================================
FILE: docs/security/2021-schema-xss-phishing-attack.md
================================================
## GraphQL Playground introspection schema template injection attack: Advisory Statement

This is a security advisory for an XSS vulnerability in `graphql-playground`.

A similar vulnerability affects `graphiql`, the package from which `graphql-playground` was forked. There is a corresponding `graphiql` [advisory](https://github.com/graphql/graphiql/security/advisories/GHSA-x4r7-m2q9-69c8).

- [1. Impact](#1-impact)
- [2. Scope](#2-scope)
- [3. Patches](#3-patches)
- [4. Reproducing the exploit](#4-reproducing-the-exploit)
- [5. Credit](#5-credit)
- [6. For more information](#6-for-more-information)

### 1. Impact

All versions of `graphql-playground-react` older than `graphql-playground-react@1.7.28` are vulnerable to compromised HTTP schema introspection responses or `schema` prop values with malicious GraphQL type names, exposing a dynamic XSS attack surface that can allow code injection on operation autocomplete.

In order for the attack to take place, the user must load a malicious schema in `graphql-playground`. There are several ways this can occur, including by specifying the URL to a malicious schema in the `endpoint` query parameter. If a user clicks on a link to a GraphQL Playground installation that specifies a malicious server, arbitrary JavaScript can run in the user's browser, which can be used to exfiltrate user credentials or other harmful goals.

### 2. Scope

This advisory describes the impact on the `graphql-playground-react` package. The vulnerability also affects `graphiql`, the package from which `graphql-playground` was forked, with a less severe impact; see the [`graphiql` advisory](https://github.com/graphql/graphiql/security/advisories/GHSA-x4r7-m2q9-69c8) for details. It affects all versions of `graphql-playground-react` older than `v1.7.28`.

This vulnerability was introduced with the first public release of `graphql-playground`, so it impacts both the original legacy `graphql-playground` and the contemporary `graphql-playground-react` npm package. It is most easily exploited on `graphql-playground-react@1.7.0` and newer, as that release added functionality which made it possible to override the endpoint URL via query parameter even if it is explicitly specified in the code.

`graphql-playground-react` is commonly loaded via the `graphql-playground-html` package or a middleware package that wraps it (`graphql-playground-express`, `graphql-playground-middleware-koa`, `graphql-playground-middleware-hapi`, or `graphql-playground-middleware-lambda`). By default, these packages render an HTML page which loads the *latest* version of `graphql-playground-react` through a CDN. If you are using one of these packages to install GraphQL Playground on your domain *and you do not explicitly pass the `version` option to `renderPlaygroundPage` or the middleware function*, then you do not need to take any action to resolve this vulnerability, as the latest version of the React app will automatically be loaded.

`graphql-playground-react` is also commonly loaded via HTML served by Apollo Server. Apollo Server always pins a specific version of `graphql-playground-react`, so if you are using Apollo Server you do need to take action to resolve this vulnerability. See the [Apollo Server advisory](https://github.com/apollographql/apollo-server/security/advisories/GHSA-qm7x-rc44-rrqw) for details.


### 3. Patches

`graphql-playground-react@1.7.28` addresses this issue via defense in depth:

- **HTML-escaping text** that should be treated as text rather than HTML. In most of the app, this happens automatically because React escapes all interpolated text by default. However, one vulnerable component uses the unsafe `innerHTML` API and interpolated type names directly into HTML. We now properly escape that type name, which fixes the known vulnerability.

- **Validates the schema** upon receiving the introspection response or schema changes. Schemas with names that violate the GraphQL spec will no longer be loaded. (This includes preventing the Doc Explorer from loading.) This change is also sufficient to fix the known vulnerability.

- **Ensuring that user-generated HTML is safe**. Schemas can contain Markdown in `description` and `deprecationReason` fields, and the web app renders them to HTML using the `markdown-it` library. Prior to `graphql-playground-react@1.7.28`, GraphQL Playground used two separate libraries to render Markdown: `markdown-it` and `marked`. As part of the development of `graphql-playground-react@1.7.28`, we verified that our use of `markdown-it` prevents the inclusion of arbitrary HTML. We use `markdown-it` without setting `html: true`, so we are comfortable relying on [`markdown-it`'s HTML escaping](https://github.com/markdown-it/markdown-it/blob/master/docs/security.md) here. We considered running a second level of sanitization over all rendered Markdown using a library such as `dompurify` but believe that is unnecessary as `markdown-it`'s sanitization appears to be adequate. `graphiql@1.4.3` does update to the latest version of `markdown-it` (v12, from v10) so that any security fixes in v11 and v12 will take effect. On the other hand, [`marked`](https://github.com/markedjs/marked) recommends the use of a separate HTML sanitizer if its input is untrusted. In this release, we switch the one component which uses `marked` to use `markdown-it` like the rest of the app.

**If you are using `graphql-playground-react` directly in your client app**, upgrade to version 1.7.28 or later.

**If you are using `graphql-playground-html` or a package which starts with `graphql-playground-middleware-` in your server** and you are passing the `version` option to a function imported from that package, change that `version` option to be at least `"1.7.28"`.

**If you are using `graphql-playground-html` or a package which starts with `graphql-playground-middleware-` in your server** and you are **NOT** passing the `version` option to a function imported from that package, no action is necessary; your app automatically loads the latest version of `graphql-playground-react` from CDN.


### 4. Reproducing the exploit

We are hosting a "malicious" server at https://graphql-xss-schema.netlify.app/graphql . This server has a hard-coded introspection result that includes unsafe HTML in type names.

If you manually change a GraphQL Playground installation to use that endpoint, clear the operation pane, and type `{x` into the operation pane, an alert will pop up; this demonstrates execution of code provided by the malicious server.

An URL like https://YOUR-PLAYGROUND-SERVER/?endpoint=https%3A%2F%2Fgraphql-xss-schema.netlify.app%2Fgraphql&query=%7B will load already configured with the endpoint in question. (This URL-based exploit works on `graphql-playground-react@1.7.0` and newer; older versions may be protected from this particular URL-based exploit depending on their configuration.)
### 5. Credit

This vulnerability was discovered by [@Ry0taK](https://github.com/Ry0taK), thank you! :1st_place_medal:

Others who contributed:

- extensive help from [@glasser](https://github.com/glasser) at [Apollo](https://github.com/apollographql)
- [@acao](https://github.com/acao)
- [@imolorhe](https://github.com/imolorhe)
- [@divyenduz](https://github.com/divyenduz)
- [@dotansimha](https://github.com/dotansimha)
- [@timsuchanek](http://github.com/timsuchanek)
- [@benjie](https://github.com/Ry0taK) and many others who provided morale support

### 6. For more information

If you have any questions or comments about this advisory:

- The `graphiql` advisory document contains [more information](https://github.com/graphql/graphiql/blob/main/docs/security/2021-introspection-schema-xss.md#2-more-details-on-the-vulnerability) about how both the client-side and server-side vulnerabilities work
- Open an issue in the [graphql-playground repo](https://github.com/graphql/graphql-playground/new/issues)


================================================
FILE: lerna.json
================================================
{
  "version": "independent",
  "packages": ["packages/*"],
  "npmClient": "yarn",
  "useWorkspaces": true,
  "command": {
    "publish": {
      "allowBranch": ["main"],
      "preDistTag": "next",
      "distTag": "latest",
      "conventionalCommits": true
    },
    "version": {
      "ignoreChanges": [
        "'__tests__' '**/*.spec.js' '**/*.spec.js' '**/*.spec.ts'",
        "**/examples/**",
        "**/public/**",
        "public/**",
        "packages/*/yarn.lock",
        "**/*.md"
      ],
      "message": "chore(release): publish"
    }
  }
}


================================================
FILE: package.json
================================================
{
  "private": true,
  "workspaces": [
    "packages/*"
  ],
  "scripts": {
    "build": "bash scripts/build.sh",
    "show-versions": "bash scripts/versions.sh",
    "release-html": "bash scripts/release-html.sh",
    "release-react": "bash scripts/release-react.sh",
    "prepublishOnly": "yarn build"
  },
  "devDependencies": {
    "@hapi/hapi": "19.1.1",
    "@types/node": "12.12.34",
    "aws-lambda": "1.0.5",
    "express": "4.17.1",
    "koa": "2.11.0",
    "lerna": "^3.22.0",
    "rimraf": "3.0.2"
  },
  "dependencies": {
    "dotenv": "8.2.0"
  }
}


================================================
FILE: packages/graphql-playground-electron/.babelrc
================================================
{
  "presets": [
    "@babel/preset-env", "@babel/preset-react"
  ],
  "plugins": [
    "styled-jsx-postcss/babel",
    "@babel/plugin-proposal-object-rest-spread",
    "babel-plugin-styled-components"
  ]
}


================================================
FILE: packages/graphql-playground-electron/.gitignore
================================================
.DS_STORE
*.log
.vscode
node_modules
dist
.tmp
lib
.idea
*.iml
*.swp
*.swo
.envrc
.netlify
.tags
.yarnclean
.awcache
dll
.happypack
build-electron


================================================
FILE: packages/graphql-playground-electron/CHANGELOG.md
================================================
# Change Log

All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [1.8.15](https://github.com/graphcool/graphql-playground/compare/graphql-playground-electron@1.8.14...graphql-playground-electron@1.8.15) (2020-10-20)

**Note:** Version bump only for package graphql-playground-electron





## [1.8.14](https://github.com/graphcool/graphql-playground/compare/graphql-playground-electron@1.8.13...graphql-playground-electron@1.8.14) (2020-09-15)

**Note:** Version bump only for package graphql-playground-electron





## [1.8.13](https://github.com/graphcool/graphql-playground/compare/graphql-playground-electron@1.8.12...graphql-playground-electron@1.8.13) (2020-08-30)

**Note:** Version bump only for package graphql-playground-electron





## [1.8.12](https://github.com/graphcool/graphql-playground/compare/graphql-playground-electron@1.8.11...graphql-playground-electron@1.8.12) (2020-08-30)


### Bug Fixes

* upgrades, schema viewer display & width adjustment ([2bb34bb](https://github.com/graphcool/graphql-playground/commit/2bb34bb8fb8c356e10435727a3f82cd23464b6b6))





## 1.8.11 (2020-06-07)


### Bug Fixes

* hapi and koa mws for next release ([#1217](https://github.com/graphcool/graphql-playground/issues/1217)) ([40c35fc](https://github.com/graphcool/graphql-playground/commit/40c35fc4c73b939d002c9d2dff51eed5dd0b6aa9))
* **deps:** [security] bump lodash.merge ([2e6b2e5](https://github.com/graphcool/graphql-playground/commit/2e6b2e5fc59c9f7fbbad5398d0defc1a0b3bd849))
* **deps:** [security] bump minimist ([a77ca5d](https://github.com/graphcool/graphql-playground/commit/a77ca5d64d9fe7b209e8a732d189570ba750eb3e))
* **deps:** update deps and toolchain, move back to using yarn… ([#1191](https://github.com/graphcool/graphql-playground/issues/1191)) ([824c7a5](https://github.com/graphcool/graphql-playground/commit/824c7a57f0284f022726a8b8840aafc3e8720ccd))
* **deps-dev:** [security] bump electron ([98ffd72](https://github.com/graphcool/graphql-playground/commit/98ffd722362820a867a9eef9ef51e5098f45afde))
* **deps-dev:** [security] bump webpack-dev-server ([a0a784d](https://github.com/graphcool/graphql-playground/commit/a0a784dd57af53799e781b876c9c80354e37c6a0))



## 1.8.10 (2019-02-23)



## 1.8.9 (2019-02-01)



## 1.8.7 (2019-01-28)



## 1.8.2 (2018-11-14)



# 1.8.0 (2018-10-16)


### Features

* update graphql-config dependency ([bb6baa1](https://github.com/graphcool/graphql-playground/commit/bb6baa1c26a0f72af73018acbe722c979f892322))



## 1.6.2 (2018-07-06)



## 1.6.1 (2018-06-26)



# 1.6.0 (2018-05-31)


### Bug Fixes

* **deps:** update dependency styled-jsx to v2.2.6 ([#543](https://github.com/graphcool/graphql-playground/issues/543)) ([b110cc9](https://github.com/graphcool/graphql-playground/commit/b110cc95c3d68cb7fae136b5d1dbbeb49b8a603d))



## 1.5.9 (2018-05-25)


### Bug Fixes

* update react dep ([9588758](https://github.com/graphcool/graphql-playground/commit/95887589a7d56570ce6007cd7d164bfc89c8a690))



## 1.5.7 (2018-05-08)


### Bug Fixes

* bump version ([2fdab26](https://github.com/graphcool/graphql-playground/commit/2fdab263f904fc38e3373f5cc3c8dcaa9342d42e))



## 1.5.6 (2018-04-24)


### Bug Fixes

* **electron:** update graphql-config-extension-prisma ([8fd45a1](https://github.com/graphcool/graphql-playground/commit/8fd45a1c27172722c335b4c84b793813c2d52b7e))



## 1.5.4 (2018-04-12)



## 1.5.2 (2018-04-02)



## 1.5.1 (2018-04-02)



# 1.5.0 (2018-04-01)



# 1.5.0-rc.5 (2018-03-28)


### Bug Fixes

* **electron:** endpoint injection ([39a1110](https://github.com/graphcool/graphql-playground/commit/39a1110a0284ef05c73ada3892c585c85e6e14a2))



# 1.5.0-rc.4 (2018-03-26)



# 1.5.0-rc.2 (2018-03-26)



# 1.5.0-rc.1 (2018-03-23)



## 1.4.5 (2018-03-15)



## 1.4.4 (2018-03-02)


### Bug Fixes

* **deps:** rm not needed graphql-playground dep ([79b3ef1](https://github.com/graphcool/graphql-playground/commit/79b3ef1f987484923c272dbbc18890433e5f3340))
* **deps:** update dependency electron-updater to v2.20.1 ([#528](https://github.com/graphcool/graphql-playground/issues/528)) ([ab2e9c3](https://github.com/graphcool/graphql-playground/commit/ab2e9c3d43f2225b546d93473bbde47535365f8e))
* **deps:** update dependency graphql-config-extension-graphcool to v1.0.6 ([#545](https://github.com/graphcool/graphql-playground/issues/545)) ([9ef55be](https://github.com/graphcool/graphql-playground/commit/9ef55bec0fd3359121ab65fa2a5ff55231feeaec))
* **deps:** update deps ([c17a8d2](https://github.com/graphcool/graphql-playground/commit/c17a8d25779ba7d3e6e0b18e9b45df86c410c4f5))
* **deps:** update deps in electron app ([772a04c](https://github.com/graphcool/graphql-playground/commit/772a04cfc684c2e38c376a9ef3abe311090c96d4))
* **settings:** Expose settings programmatically, update deps ([0356557](https://github.com/graphcool/graphql-playground/commit/03565573869f240675aaa5399bb5f0ac097455c5))



## 1.4.2 (2018-01-22)



## 1.4.1 (2018-01-22)


### Bug Fixes

* **electron:** Add zoom on CMD + and CMD - ([cc2c4ed](https://github.com/graphcool/graphql-playground/commit/cc2c4edc48c986aa55a76c56362e5109eb393b1f))
* **electron:** postcss config ([55187dc](https://github.com/graphcool/graphql-playground/commit/55187dcbed2be9c48f24424e6d3ee5f2d60e11e5))



## 1.3.24 (2018-01-13)


### Bug Fixes

* **build:** Fix build, temporarily disable yarn workspace, update graphcool-styles & graphcool-ui de ([af501d7](https://github.com/graphcool/graphql-playground/commit/af501d7a754a14dbacc76439a77434f892828482))
* **deps:** Updated graphql-config-extension-graphcool ([ef83c09](https://github.com/graphcool/graphql-playground/commit/ef83c097c018a42f7ee65529d6af4ea3928a4281))



## 1.3.21 (2018-01-04)



## 1.3.20 (2018-01-04)



## 1.3.19 (2018-01-03)


### Bug Fixes

* electron without graphql config ([bf5a722](https://github.com/graphcool/graphql-playground/commit/bf5a722f484a644a1a64e536ba6bd375dbfce928))



## 1.3.17 (2018-01-03)



## 1.3.16 (2017-12-27)



## 1.3.14 (2017-12-26)



## 1.3.12 (2017-12-24)



## 1.3.10 (2017-12-20)


### Bug Fixes

* should suggest `graphql-cli` instead of `graphql` ([bbfa0ca](https://github.com/graphcool/graphql-playground/commit/bbfa0ca935dea618208f76c58b86363f27ddf595))



## 1.3.9 (2017-12-14)



## 1.3.8-beta.1 (2017-12-12)


### Bug Fixes

* Capture keyboard event so it's always called (regardless of any stopPropagation by children) ([56634d0](https://github.com/graphcool/graphql-playground/commit/56634d0c7079854888a7d2d5ec0936d8fd0b06a5))
* change package.json > author > url to match URI schema ([0a84b89](https://github.com/graphcool/graphql-playground/commit/0a84b89f6a94aeecdf48217b1de661181e0b5741))


### Features

* Add Settings to the menu with the shortcut to open on CMD + , (Fixes [#290](https://github.com/graphcool/graphql-playground/issues/290)) ([ead0cae](https://github.com/graphcool/graphql-playground/commit/ead0cae5c4d069f87b61a6cd17d5855f5e215b81))



# 1.3.0 (2017-12-01)



# 1.2.0 (2017-11-24)



## 1.1.1 (2017-11-03)


### Bug Fixes

* **desktop:** allow urls without tld - fixes [#138](https://github.com/graphcool/graphql-playground/issues/138) ([be3d2cf](https://github.com/graphcool/graphql-playground/commit/be3d2cfe219211393b6438332b553e6e3d9b7493))


================================================
FILE: packages/graphql-playground-electron/README.md
================================================
# Playground

Repository for the electron playground app.

## Development
```sh
yarn install
yarn start
```

## Production build

```sh
yarn release
```

This will create a `build-electron` folder where you will have the compiled electron app. (The assets will automatically be uploaded to Github if the `GH_TOKEN` env variable is set. See [here](https://www.electron.build/publishing-artifacts) for more.)


================================================
FILE: packages/graphql-playground-electron/package.json
================================================
{
  "name": "graphql-playground-electron",
  "productName": "GraphQL Playground",
  "homepage": "https://github.com/graphcool/graphql-playground",
  "repository": "graphcool/graphql-playground",
  "description": "GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration)",
  "version": "1.8.15",
  "private": true,
  "author": {
    "name": "Graphcool",
    "email": "hello@graph.cool",
    "url": "https://www.graph.cool"
  },
  "main": "lib/main",
  "build": {
    "appId": "cool.graph.playground",
    "mac": {
      "category": "public.app-category.developer-tools",
      "icon": "static/icons/icon.icns"
    },
    "win": {
      "icon": "static/icons/icon.ico"
    },
    "linux": {
      "category": "Development",
      "target": [
        "AppImage",
        "snap",
        "deb"
      ]
    },
    "nsis": {
      "oneClick": false,
      "perMachine": true,
      "allowElevation": true,
      "allowToChangeInstallationDirectory": true,
      "runAfterFinish": false
    },
    "files": [
      "lib/**/!(*.map)"
    ],
    "directories": {
      "output": "build-electron"
    },
    "fileAssociations": {
      "ext": "graphql",
      "name": "GraphQL",
      "role": "Editor"
    },
    "protocols": {
      "name": "graphql-playground-protocol",
      "schemes": [
        "graphql-playground"
      ]
    }
  },
  "scripts": {
    "build:ts": "rimraf lib && tsc",
    "build:webpack": "rimraf ./dist && NODE_ENV=production GRAPHQL_ENDPOINT=$BACKEND_ADDR/system webpack --config webpack.config.build.js && cp -r static/* dist",
    "build": "npm run build:ts && npm run build:webpack && cp -r dist lib && rimraf ./build:electron",
    "release": "npm run build && electron-builder -lmw",
    "release:mac": "npm run build && electron-builder -m",
    "release:win": "npm run build && electron-builder -w",
    "release:linux": "npm run build && electron-builder -l",
    "library": "rimraf .happypack && NODE_ENV=production webpack --config webpack.library.js -p",
    "lint": "tslint \"src/**/*.ts{,x}\" && lint-staged",
    "start": "yarn build:ts && concurrently \"yarn start:react\" \"wait-on http://localhost:4040/ && yarn start:electron\"",
    "start:react": "webpack-dev-server --hot --profile --history-api-fallback --host 0.0.0.0 --port 4040",
    "start:electron": "electron lib/main",
    "stats": "NODE_ENV=production webpack --config webpack.library.js  --profile --json > stats.json",
    "test": "npm run lint",
    "precommit": "lint-staged",
    "prettier": "prettier --single-quote --no-semi --trailing-comma all --write '*.{js,ts,tsx}' 'src/**/*.{js,ts,tsx}'"
  },
  "lint-staged": {
    "*.{ts,tsx}": [
      "prettier --single-quote --no-semi --trailing-comma all --write",
      "tslint",
      "git add"
    ]
  },
  "pre-push": [
    "test-quick"
  ],
  "dependencies": {
    "@types/ms": "0.7.30",
    "classnames": "2.2.5",
    "core-js": "^3.6.5",
    "date-fns": "1.29.0",
    "electron-is-dev": "0.3.0",
    "electron-localshortcut": "3.1.0",
    "electron-log": "2.2.14",
    "electron-updater": "^4.0.0",
    "find-up": "^2.1.0",
    "graphcool-styles": "0.2.7",
    "graphcool-ui": "^0.0.14",
    "graphql": "^15.3.0",
    "graphql-config": "^2.2.2",
    "graphql-config-extension-graphcool": "^1.0.11",
    "graphql-config-extension-prisma": "^0.3.0",
    "graphql-playground-html": "^1.6.29",
    "graphql-playground-react": "^1.7.27",
    "immutable": "4.0.0-rc.9",
    "js-yaml": "^3.11.0",
    "lodash.merge": "^4.6.2",
    "minimist": "^1.2.3",
    "ms": "^2.1.1",
    "query-string": "^5.0.1",
    "raven": "^2.4.2",
    "react": "16.13.1",
    "react-dom": "^16.4.0",
    "react-redux": "^7.2.1",
    "redux": "^4.0.5",
    "redux-localstorage": "^1.0.0-rc5",
    "redux-localstorage-filter": "^0.1.1",
    "regenerator-runtime": "^0.13.7",
    "reselect": "^3.0.1",
    "semver": "^5.5.0",
    "styled-jsx": "2.2.6",
    "styled-jsx-postcss": "git+https://github.com/timsuchanek/styled-jsx-postcss#build3",
    "sweetalert2": "^7.21.0",
    "validator": "^9.2.0"
  },
  "devDependencies": {
    "@babel/cli": "^7.0.0",
    "@babel/core": "^7.0.0",
    "@babel/plugin-proposal-class-properties": "^7.0.0",
    "@babel/plugin-proposal-json-strings": "^7.0.0",
    "@babel/plugin-syntax-dynamic-import": "^7.0.0",
    "@babel/plugin-syntax-import-meta": "^7.0.0",
    "@babel/plugin-transform-runtime": "^7.12.0",
    "@babel/preset-env": "^7.0.0",
    "@babel/preset-react": "^7.0.0",
    "@types/classnames": "2.2.3",
    "@types/deasync": "0.1.0",
    "@types/jest": "22.2.3",
    "@types/node": "12.12.34",
    "@types/react": "16.9.32",
    "@types/react-addons-test-utils": "0.14.20",
    "@types/react-dom": "~16.9.6",
    "@types/react-redux": "7.1.9",
    "@types/zen-observable": "^0.5.3",
    "awesome-typescript-loader": "5.0.0",
    "babel-core": "^7.0.0-bridge.0",
    "babel-jest": "^23.4.2",
    "babel-loader": "^8.0.0",
    "babel-plugin-styled-components": "^1.8.0",
    "babili-webpack-plugin": "0.1.2",
    "concurrently": "3.5.1",
    "css-loader": "0.28.11",
    "electron": "2.0.18",
    "electron-builder": "^22.8.1",
    "electron-devtools-installer": "3.1.1",
    "extract-text-webpack-plugin": "3.0.2",
    "file-loader": "1.1.11",
    "fork-ts-checker-webpack-plugin": "0.4.1",
    "happypack": "5.0.0",
    "html-loader": "^1.3.1",
    "html-webpack-plugin": "3.2.0",
    "identity-obj-proxy": "3.0.0",
    "json-loader": "0.5.7",
    "lint-staged": "7.1.2",
    "node-noop": "1.0.0",
    "polished": "1.9.2",
    "postcss-inherit": "git+https://github.com/timsuchanek/postcss-inherit#build3",
    "postcss-loader": "0.9.1",
    "postcss-simple-vars": "3.1.0",
    "prettier": "2.0.2",
    "raw-loader": "0.5.1",
    "react-addons-test-utils": "15.6.2",
    "react-test-renderer": "16.4.0",
    "redux-mock-store": "1.5.1",
    "rimraf": "3.0.2",
    "style-loader": "0.20.1",
    "svgo-loader": "1.2.1",
    "ts-loader": "3.4.0",
    "tslint": "5.10.0",
    "tslint-graphcool-frontend": "0.0.3",
    "tslint-loader": "3.6.0",
    "typescript": "3.8.3",
    "url-loader": "0.6.2",
    "wait-on": "2.1.0",
    "webpack": "4.44.1",
    "webpack-bundle-analyzer": "3.3.2",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "3.11.0",
    "webpack-uglify-parallel": "0.1.4"
  },
  "resolutions": {
    "**/graphql": "0.13.2",
    "**/**/graphql": "0.13.2",
    "**/**/**/graphql": "0.13.2",
    "**/**/**/**/graphql": "0.13.2",
    "**/**/**/**/**/graphql": "0.13.2",
    "**/**/**/**/**/**/graphql": "0.13.2"
  }
}


================================================
FILE: packages/graphql-playground-electron/postcss.config.js
================================================
module.exports = ctx => ({
  plugins: [
    require('postcss-simple-vars')({
      variables: () => require('graphcool-styles/dist/variables/variables.js'),
    }),
    require('postcss-inherit')({
      globalStyles: 'node_modules/graphcool-styles/dist/styles.css',
      propertyRegExp: /^(inherit|extend|p)s?:?$/i,
    }),
  ],
})


================================================
FILE: packages/graphql-playground-electron/src/main/createWindow.ts
================================================
import { BrowserWindow, app, ipcMain } from 'electron'
import * as path from 'path'
import dev = require('electron-is-dev')
import { newWindowConfig } from '../shared/utils'
import * as log from 'electron-log'
import { WindowContext } from './types'

export function createWindow(windowContext: WindowContext) {
  // Create the browser window.
  const newWindow = new BrowserWindow(newWindowConfig)

  newWindow.loadURL(
    dev
      ? 'http://localhost:4040' // Dev server ran by react-scripts
      : `file://${path.join(__dirname, '..', '/dist/index.html')}`, // Bundled application
  )

  if (dev) {
    // If dev mode install react and redux extension
    // Also open the devtools
    const {
      default: installExtension,
      REACT_DEVELOPER_TOOLS,
      REDUX_DEVTOOLS,
    } = require('electron-devtools-installer')

    installExtension(REACT_DEVELOPER_TOOLS)
      .then(name => log.info(`Added Extension:  ${name}`))
      .catch(err => log.info('An error occurred: ', err))

    installExtension(REDUX_DEVTOOLS)
      .then(name => log.info(`Added Extension:  ${name}`))
      .catch(err => log.info('An error occurred: ', err))

    // newWindow.webContents.openDevTools()
  }

  windowContext.windows.add(newWindow)
  windowContext.windowById.set(newWindow.id, newWindow)

  // Emitted when the window is closed.
  const id = newWindow.id
  newWindow.on('closed', () => {
    if (process.platform !== 'darwin' && windowContext.windows.size === 0) {
      app.quit()
    }
    windowContext.windows.delete(newWindow)
    windowContext.windowById.delete(id)
    windowContext.windowByPath.forEach((window, cwd) => {
      if (window === newWindow) {
        windowContext.windowByPath.delete(cwd)
      }
    })
  })

  // electronLocalShortcut.register(newWindow, 'Cmd+Shift+]', () => {
  //   send('Tab', 'Next')
  // })

  // electronLocalShortcut.register(newWindow, 'Cmd+Shift+[', () => {
  //   send('Tab', 'Prev')
  // })

  windowContext.readyWindowsPromises[newWindow.id] = new Promise(resolve =>
    ipcMain.once('ready', resolve),
  )

  return newWindow
}


================================================
FILE: packages/graphql-playground-electron/src/main/index.ts
================================================
// TODO enable tslint
// /* tslint:disable */
import {
  app,
  BrowserWindow,
  globalShortcut,
  ipcMain,
  protocol,
  Menu,
} from 'electron'
import * as queryString from 'query-string'
import * as fs from 'fs'
import * as log from 'electron-log'
import { buildTemplate } from './menu'
import { createWindow } from './createWindow'
import { WindowContext } from './types'
import { startUpdates } from './updates'
import * as Raven from 'raven'
Raven.config(
  'https://cce868d3730e473e9350f1436da7d908:ff5d65389e404b28b5af1d97d8024414@sentry.io/297194',
).install()

log.transports.file.level = 'info'
log.transports.console.level = 'debug'


const windowContext: WindowContext = {
  readyWindowsPromises: {},
  windows: new Set(),
  windowById: new Map(),
  windowByPath: new Map(),
}

let appResolve
const appPromise = new Promise(resolve => (appResolve = resolve))

app.setAsDefaultProtocolClient('graphql-playground')

app.on('open-url', (event, url) => {
  event.preventDefault()

  const cutIndex = url.indexOf('//')
  const query = url.slice(cutIndex + 2)
  const input = queryString.parse(query)
  let env
  if (input.env) {
    try {
      env = JSON.parse(input.env)
    } catch (e) {
      // could
      console.log('could not get env')
    }
  }
  if (input.envPath) {
    try {
      env = JSON.parse(fs.readFileSync(input.envPath, 'utf-8'))
      fs.unlinkSync(input.envPath)
    } catch (e) {
      //
    }
  }
  const msg = JSON.stringify({
    ...input,
    env,
  })
  forceSend('OpenUrl', msg, input.cwd)
})

app.on('open-file', (event, filePath) => {
  event.preventDefault()
  forceSend('OpenSelectedFile', filePath, filePath)
})

ipcMain.on('online-status-changed', (event, status) => {
  process.env.CONNECTION = status
})

ipcMain.on('async', (event, arg) => {
  const focusedWindow = BrowserWindow.getFocusedWindow()
  if (focusedWindow) {
    focusedWindow.close()
  }
})

ipcMain.on('cwd', (event, msg) => {
  const { cwd, id } = JSON.parse(msg)
  const window = windowContext.windowById.get(id)
  windowContext.windowByPath.set(cwd, window)
})

ipcMain.on('CloseWindow', (event, msg) => {
  const { id } = JSON.parse(msg)
  const window = windowContext.windowById.get(id)
  window.close()
})

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', () => {
  createWindow(windowContext)

  startUpdates()

  const menu = Menu.buildFromTemplate(buildTemplate(windowContext))
  Menu.setApplicationMenu(menu)

  ipcMain.on('get-file-data', event => {
    log.info('get-file-data', event)
    // this.fileAdded(event)
  })

  ipcMain.on('load-file-content', (event, filePath) => {
    log.info('load-file-content', event, filePath)
  })

  protocol.registerFileProtocol('file:', (request, filePath) => {
    log.info('file:', request, filePath)
  })

  if (appResolve) {
    appResolve()
  }
})

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', () => {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow(windowContext)
  }
})

app.on('will-quit', () => {
  // Unregister all shortcuts.
  globalShortcut.unregisterAll()
})

async function forceSend(channel: string, arg: string, byPath?: string) {
  await appPromise

  const currentWindows = BrowserWindow.getAllWindows()
  let window
  if (byPath) {
    window = windowContext.windowByPath.get(byPath)
    if (
      !window &&
      currentWindows.length === 1 &&
      windowContext.windowByPath.size === 0
    ) {
      window = currentWindows[0]
    }
  } else {
    window = currentWindows[0]
  }
  let destroyed = null
  try {
    destroyed = window ? window.isDestroyed() : null
  } catch (e) {
    //
  }
  if (!window || destroyed) {
    window = createWindow(windowContext)
  }
  await windowContext.readyWindowsPromises[window.id]
  window.webContents.send(channel, arg)
}


================================================
FILE: packages/graphql-playground-electron/src/main/menu.ts
================================================
import {
  MenuItemConstructorOptions,
  BrowserWindow,
  app,
  autoUpdater,
} from 'electron'
import * as log from 'electron-log'
import { WindowContext } from './types'
import { createWindow } from './createWindow'
import { notify } from './notify'

export const buildTemplate = (
  windowContext: WindowContext,
): MenuItemConstructorOptions[] => [
  {
    label: 'Application',
    submenu: [
      {
        label: 'About GraphQL Playground',
        selector: 'orderFrontStandardAboutPanel:',
      } as MenuItemConstructorOptions,
      {
        label: 'Check For Updates',
        click: () => {
          autoUpdater.once('update-not-available', () => {
            notify({
              title: 'GraphQL Playground Updates',
              body: 'Already up to date.',
            })
          })

          autoUpdater.checkForUpdates()
        },
      },
      { type: 'separator' },
      {
        label: 'Settings',
        accelerator: 'CmdOrCtrl+,',
        click: () => send('Tab', 'Settings'),
      },
      { type: 'separator' },
      {
        label: 'Hide GraphQL Playground',
        accelerator: 'Cmd+H',
        role: 'hide',
      },
      {
        label: 'Hide Others',
        accelerator: 'Option+Cmd+H',
        role: 'hideOthers',
      },
      {
        label: 'Show All',
        role: 'unhide',
      },
      { type: 'separator', visible: process.platform === 'darwin' },
      {
        label: 'Quit',
        accelerator: 'CmdOrCtrl+Q',
        click: () => app.quit(),
      },
    ],
  },
  {
    label: 'Workspace',
    submenu: [
      {
        label: 'New Workspace',
        accelerator: 'CmdOrCtrl+N',
        click: () => {
          createWindow(windowContext)
        },
      },
      {
        label: 'New Tab',
        accelerator: 'CmdOrCtrl+T',
        click: () => send('Tab', 'New'),
      },
      { type: 'separator' },
      {
        label: 'Close Workspace',
        accelerator: 'CmdOrCtrl+Shift+W',
        role: 'close',
      },
      {
        label: 'Close Tab',
        accelerator: 'CmdOrCtrl+W',
        click: () => send('Tab', 'Close'),
      },
      {
        label: 'Open File',
        accelerator: 'CmdOrCtrl+O',
        click: () => send('File', 'Open'),
      },
      {
        label: 'Save File',
        accelerator: 'CmdOrCtrl+S',
        click: () => send('File', 'Save'),
      },
      {
        label: 'Reload Schema',
        accelerator: 'CmdOrCtrl+R',
        click: () => send('Tab', 'ReloadSchema'),
      },
    ],
  },
  {
    label: 'Edit',
    submenu: [
      {
        label: 'Undo',
        accelerator: 'CmdOrCtrl+Z',
        selector: 'undo:',
      } as MenuItemConstructorOptions,
      {
        label: 'Redo',
        accelerator: 'Shift+CmdOrCtrl+Z',
        selector: 'redo:',
      } as MenuItemConstructorOptions,
      { type: 'separator' },
      {
        label: 'Cut',
        accelerator: 'CmdOrCtrl+X',
        selector: 'cut:',
      } as MenuItemConstructorOptions,
      {
        label: 'Copy',
        accelerator: 'CmdOrCtrl+C',
        selector: 'copy:',
      } as MenuItemConstructorOptions,
      {
        label: 'Paste',
        accelerator: 'CmdOrCtrl+V',
        selector: 'paste:',
      } as MenuItemConstructorOptions,
      {
        label: 'Select All',
        accelerator: 'CmdOrCtrl+A',
        selector: 'selectAll:',
      } as MenuItemConstructorOptions,
    ],
  },
  {
    label: 'Window',
    submenu: [
      {
        label: 'Next Tab',
        accelerator: 'CmdOrCtrl+Alt+Right',
        click: () => send('Tab', 'Next'),
      },
      {
        label: 'Previous Tab',
        accelerator: 'CmdOrCtrl+Alt+Left',
        click: () => send('Tab', 'Next'),
      },
      {
        label: 'Minimize',
        accelerator: 'CmdOrCtrl+M',
        click: () => {
          const focusedWindow = BrowserWindow.getFocusedWindow()
          if (focusedWindow) {
            focusedWindow.minimize()
          }
        },
      },
      { type: 'separator' },
      { label: 'Toggle Developer Tools', role: 'toggledevtools' },
    ],
  },
]

function send(channel: string, arg: string) {
  const focusedWindow = BrowserWindow.getFocusedWindow()
  if (focusedWindow) {
    log.info('sending to focused window', channel, arg)
    focusedWindow.webContents.send(channel, arg)
  } else {
    log.info('no focused window')
  }
}


================================================
FILE: packages/graphql-playground-electron/src/main/notify.ts
================================================
import { shell, Notification } from 'electron'

interface NotificationOptions {
  title: string
  body: string
  url?: string
  onClick?: () => void
}

export const notify = ({ title, body, url, onClick }: NotificationOptions) => {
  const notification = new Notification({
    title,
    body,
    silent: true,
  })

  if (url || onClick) {
    notification.on('click', () => {
      if (onClick) {
        return onClick()
      }

      shell.openExternal(url)
    })
  }

  notification.show()
  console.log(`[Notification] ${title}: ${body}`)
}


================================================
FILE: packages/graphql-playground-electron/src/main/types.ts
================================================
import { BrowserWindow } from 'electron'

export interface WindowContext {
  readyWindowsPromises: { [windowId: number]: Promise<void> }
  windows: Set<BrowserWindow>
  windowById: Map<number, BrowserWindow>
  windowByPath: Map<string, BrowserWindow>
}


================================================
FILE: packages/graphql-playground-electron/src/main/updates.ts
================================================
import { app, autoUpdater, ipcMain, BrowserWindow, dialog } from 'electron'
import ms = require('ms')
import dev = require('electron-is-dev')
import * as log from 'electron-log'
import { notify } from './notify'

export const startUpdates = () => {
  if (!dev) {
    startAppUpdates()
  }
}

const setUpdateURL = async () => {
  let betaUpdates = false

  await new Promise(resolve => {
    ipcMain.once('SettingsResponse', (event, settingsString) => {
      log.info('settings', settingsString)
      betaUpdates = getBetaUpdates(settingsString)
      resolve()
    })

    send('SettingsRequest', '')
  })

  const channel = betaUpdates ? 'kygnjrcroc' : 'ppbimurjwk'
  const server = `https://hazel-server-${channel}.now.sh/update`
  autoUpdater.setFeedURL({url: `${server}/${process.platform}/${app.getVersion()}`})
}

const checkForUpdates = async () => {
  if (process.env.CONNECTION === 'offline') {
    // Try again after half an hour
    setTimeout(checkForUpdates, ms('30m'))
    return
  }

  // Ensure we're pulling from the correct channel
  try {
    await setUpdateURL()
  } catch (err) {
    log.error(err)
    // Retry later if setting the update URL failed
    return
  }

  // Then ask the server for updates
  autoUpdater.checkForUpdates()
}

const startAppUpdates = () => {
  autoUpdater.on('error', error => {
    log.error(error)
    setTimeout(checkForUpdates, ms('15m'))
  })

  autoUpdater.on('checking-for-update', () => {
    log.info('Checking for app updates...')
  })

  autoUpdater.on('update-downloaded', () => {
    log.info('Update downloaded')
    const buttonIndex = dialog.showMessageBox({
      message: `Update downloaded. Install now?`,
      buttons: ['Install Update & Restart', 'Later'],
    })
    if (buttonIndex === 0) {
      autoUpdater.quitAndInstall()
      app.quit()
    }
  })

  autoUpdater.on('update-available', () => {
    log.info('Found update for the app! Downloading...')
    notify({
      title: 'GraphQL Playground Updates',
      body: 'Update available. Downloading...',
    })
  })

  autoUpdater.on('update-not-available', () => {
    log.info('No updates found. Checking again in 5 minutes...')
    setTimeout(checkForUpdates, ms('5m'))
  })

  setTimeout(checkForUpdates, ms('10s'))
}

function send(channel: string, arg: string) {
  const window = BrowserWindow.getAllWindows()[0]
  if (window) {
    log.info('sending to open window', channel, arg)
    window.webContents.send(channel, arg)
  } else {
    log.info('no opened window')
  }
}

function getBetaUpdates(settingsString: string | undefined): boolean {
  try {
    const settings = JSON.parse(settingsString)
    return !!settings['general.betaUpdates']
  } catch (e) {
    //
  }

  return false
}


================================================
FILE: packages/graphql-playground-electron/src/renderer/components/App.tsx
================================================
import * as React from 'react'
import 'core-js/stable'
import 'regenerator-runtime/runtime'
import { remote, ipcRenderer, webFrame } from 'electron'
import * as cx from 'classnames'
import { Playground as IPlayground } from 'graphql-playground-react/lib/components/Playground'
import { merge, set } from 'immutable'
import Playground, {
  openSettingsTab,
  selectNextTab,
  selectPrevTab,
  closeSelectedTab,
  refetchSchema,
  newSession,
  store,
  getSessionsState,
  saveFile,
  newFileTab,
  getEndpoint,
  selectAppHistoryItem,
  AppHistoryItem,
} from 'graphql-playground-react'
import {
  getGraphQLConfig,
  findGraphQLConfigFile,
  GraphQLConfigData,
  resolveEnvsInValues,
} from 'graphql-config'
import { createRemoteWindow } from '../../shared/utils'
import InitialView from './InitialView/InitialView'
import * as minimist from 'minimist'
import * as fs from 'fs'
import * as path from 'path'
import * as os from 'os'
import * as yaml from 'js-yaml'
import * as findUp from 'find-up'
import {
  patchEndpointsToConfigData as patchPrismaEndpointsToConfigData,
  makeConfigFromPath,
} from 'graphql-config-extension-prisma'
import { patchEndpointsToConfigData } from 'graphql-config-extension-graphcool'
import { connect } from 'react-redux'
import { errify } from '../utils/errify'
import { createStructuredSelector } from 'reselect'
import * as dotenv from 'dotenv'

// import { PermissionSession } from 'graphql-playground/lib/types'

const { dialog } = remote

// declare var p: IPlayground

interface State {
  endpoint?: string
  openTooltipTheme: boolean
  theme: string
  shareUrl?: string
  loading: boolean
  session?: any
  platformToken?: string
  configString?: string
  configPath?: string

  folderName?: string
  env?: any
  config?: GraphQLConfigData
}

ipcRenderer.on('SettingsRequest', () => {
  ipcRenderer.send('SettingsResponse', localStorage.getItem('settings'))
})

const events: any[] = []

ipcRenderer.on('OpenSelectedFile', pushSelectedFile)
ipcRenderer.on('OpenUrl', pushOpenUrl)

function pushSelectedFile() {
  events.push({
    type: 'OpenSelectedFile',
    args: arguments,
  })
}

function pushOpenUrl() {
  events.push({
    type: 'OpenUrl',
    args: arguments,
  })
}

interface ReduxProps {
  openSettingsTab: () => void
  selectNextTab: () => void
  selectPrevTab: () => void
  closeSelectedTab: () => void
  refetchSchema: () => void
  newSession: (endpoint: string) => void
  saveFile: () => void
  newFileTab: (fileName: string, filePath: string, file: string) => void
  selectAppHistoryItem: (item: AppHistoryItem) => void
  endpoint: string
}

class App extends React.Component<ReduxProps, State> {
  private playground: IPlayground

  constructor(props) {
    super(props)
    const { endpoint, platformToken } = this.getArgs()
    this.state = {
      openTooltipTheme: false,
      theme: 'dark',
      endpoint,
      platformToken,
      loading: false,
    }
      ; (global as any).a = this
      ; (global as any).r = remote
  }

  fileAdded = event => {
    // console.log(event)
  }

  getArgs(): any {
    const argv = remote.process.argv
    const args = minimist(argv.slice(1))

    return {
      endpoint: args.endpoint,
      subscriptionsEndpoint: args['subscriptions-endpoint'],
      platformToken:
        args['platform-token'] || localStorage.getItem('platformToken'),
      env: args.env,
    }
  }

  handleSelectEndpoint = (endpoint: string) => {
    this.setState({ endpoint } as State)
  }

  handleSelectFolder = async (folderPath: string) => {
    try {
      // Get config from folderPath
      const envPath = path.join(folderPath, '.env')
      let env = process.env
      if (fs.existsSync(envPath)) {
        const envString = fs.readFileSync(envPath)
        const localEnv = dotenv.parse(envString)
        if (localEnv) {
          env = merge(env, localEnv)
        }
      }
      const configPath = findGraphQLConfigFile(folderPath)
      const configString = fs.readFileSync(configPath, 'utf-8')

      /* tslint:disable-next-line */
      //       if (configString.includes('${env:')) {
      //         errify(`You opened a .graphqlconfig file that includes environment variables.
      // In order to use environment variables in the Playground, please start it from the graphql cli. Install with
      // npm install -g graphql-cli
      // Then open the graphql config with:
      // cd ${folderPath}; graphql playground`)
      //       }

      const configDir = path.dirname(configPath)
      let config
      try {
        config = await patchEndpointsToConfigData(
          resolveEnvsInValues(getGraphQLConfig(configDir).config, env),
          configDir,
          env,
        )
        config = await patchPrismaEndpointsToConfigData(
          resolveEnvsInValues(getGraphQLConfig(configDir).config, env),
          configDir,
          env,
        )
      } catch (e) {
        const ymlPath = path.join(configDir, 'prisma.yml')
        if (!fs.existsSync(ymlPath)) {
          throw e
        }
        config = await makeConfigFromPath(configDir)
      }

      ipcRenderer.send(
        'cwd',
        JSON.stringify({ cwd: configDir, id: remote.getCurrentWindow().id }),
      )
      const state = {
        configString,
        configPath,
        config,
        folderName: path.basename(folderPath),
        env,
      }
      this.setState(state as State)
      this.props.selectAppHistoryItem(merge(state, {
        type: 'local',
        path: configPath,
      }) as any)
    } catch (error) {
      errify(error)
    }
  }

  handleOpenNewWindow = () => {
    createRemoteWindow()
  }

  openSettingsTab = () => {
    this.props.openSettingsTab()
  }

  nextTab = () => {
    this.props.selectNextTab()
  }

  prevTab = () => {
    this.props.selectPrevTab()
  }

  newTab = () => {
    this.props.newSession(this.props.endpoint)
  }

  closeTab = () => {
    this.props.closeSelectedTab()
  }

  reloadSchema = () => {
    this.props.refetchSchema()
  }

  componentDidMount() {
    ipcRenderer.removeListener('OpenUrl', pushOpenUrl)
    ipcRenderer.removeListener('OpenSelectedFile', pushSelectedFile)
    ipcRenderer.on('Tab', this.readTabMessage)
    ipcRenderer.on('File', this.readFileMessage)
    ipcRenderer.on('OpenSelectedFile', this.readOpenSelectedFileMessage)
    ipcRenderer.on('OpenUrl', this.handleUrl)
    window.addEventListener('keydown', this.handleKeyDown, true)
    this.consumeEvents()
    ipcRenderer.send('ready', '')
    // if (
    //   !this.state.endpoint &&
    //   !this.state.config &&
    //   !this.state.configPath &&
    //   !this.state.configString
    // ) {
    //   const workspace = this.deserializeWorkspace()
    //   if (workspace) {
    //     this.setState(workspace)
    //   }
    // }
  }

  consumeEvents() {
    while (events.length > 0) {
      const event = events.shift()
      switch (event.type) {
        case 'OpenSelectedFile':
          return this.readOpenSelectedFileMessage.call(this, ...event.args)
        case 'OpenUrl':
          return this.handleUrl.call(this, ...event.args)
      }
    }
  }

  componentWillUnmount() {
    ipcRenderer.removeListener('Tab', this.readTabMessage)
    ipcRenderer.removeListener('File', this.readFileMessage)
    ipcRenderer.removeListener(
      'OpenSelectedFile',
      this.readOpenSelectedFileMessage,
    )
    ipcRenderer.removeListener('OpenUrl', this.handleUrl)
    window.removeEventListener('keydown', this.handleKeyDown, true)
  }

  handleKeyDown = e => {
    if (e.key === '{' && e.metaKey) {
      this.prevTab()
    } else if (e.key === '}' && e.metaKey) {
      this.nextTab()
    } else if (e.key >= 1 && e.key <= 9 && e.metaKey) {
      this.playground.switchTab(e.key)
    } else if (e.key === '=' && e.metaKey) {
      const zoom = webFrame.getZoomFactor()
      webFrame.setZoomFactor(zoom + 0.1)
    } else if (e.key === '-' && e.metaKey) {
      const zoom = webFrame.getZoomFactor()
      webFrame.setZoomFactor(zoom - 0.1)
    }
  }

  handleUrl = async (event, msg) => {
    const input = JSON.parse(msg)

    const endpoint = input.endpoint
    let configString
    let folderName
    let configPath
    const platformToken = input.platformToken
    let config

    if (input.cwd) {
      // use the endpoint as an alternative, only log the error
      try {
        configPath = findUp.sync(['.graphqlconfig', '.graphqlconfig.yml'], {
          cwd: input.cwd,
        })
        configString = configPath
          ? fs.readFileSync(configPath, 'utf-8')
          : undefined
        folderName = configPath
          ? path.basename(path.dirname(configPath))
          : undefined
        try {
          const rawConfig = getGraphQLConfig(input.cwd).config
          const resolvedConfig = resolveEnvsInValues(rawConfig, input.env)
          config = await patchEndpointsToConfigData(
            resolvedConfig,
            input.cwd,
            input.env,
          )
          config = await patchPrismaEndpointsToConfigData(
            resolvedConfig,
            input.cwd,
            input.env,
          )
        } catch (e) {
          const ymlPath = path.join(input.cwd, 'prisma.yml')
          if (!fs.existsSync(ymlPath)) {
            throw e
          }
          config = (await makeConfigFromPath(input.cwd, input.env)).config
          configPath = ymlPath
          folderName = path.basename(input.cwd)
          configString = JSON.stringify(config)
        }

        if (!this.configContainsEndpoints(config)) {
          const graphcoolNote = configString.includes('graphcool')
            ? 'Please make sure to add stages to your graphcool.yml'
            : ''
          errify(
            `${configPath} does not include any endpoints. ${graphcoolNote}`,
          )
          return
        }
      } catch (e) {
        console.error(e)
        errify(e)
      }
    }

    ipcRenderer.send(
      'cwd',
      JSON.stringify({ cwd: input.cwd, id: remote.getCurrentWindow().id }),
    )

    const state = {
      configString,
      folderName,
      configPath,
      env: input.env,
      endpoint,
      config,
      platformToken,
    }

    this.props.selectAppHistoryItem(merge(state, {
      type: 'endpoint',
      path: configPath,
    }) as any)

    this.setState(state)
  }

  configContainsEndpoints(config: GraphQLConfigData): boolean {
    if (
      Object.keys((config.extensions && config.extensions.endpoints) || {})
        .length > 0
    ) {
      return true
    }
    return Object.keys(config.projects).reduce((acc, curr) => {
      const project = config.projects[curr]
      if (
        project.extensions &&
        project.extensions.endpoints &&
        Object.keys(project.extensions.endpoints).length > 0
      ) {
        return true
      }

      return acc
    }, false)
  }

  readFileMessage = (event, message) => {
    switch (message) {
      case 'Open':
        this.showOpenDialog()
        break
      case 'Save':
        this.getSaveFileName()
        break
    }
  }

  readOpenSelectedFileMessage = (event, selectedFile) => {
    if (selectedFile) {
      this.openFile(selectedFile)
    }
  }

  async openFile(fileName: string) {
    const file = fs.readFileSync(fileName, 'utf-8')
    if (!this.playground) {
      this.handleSelectFolder(path.dirname(fileName))
    }
    while (!this.playground) {
      await new Promise(r => setTimeout(r, 200))
    }
    await new Promise(r => setTimeout(r, 200))
    this.props.newFileTab(path.basename(fileName), fileName, file)
  }

  showOpenDialog() {
    dialog.showOpenDialog(
      {
        title: 'Choose a .graphql file to edit',
        properties: ['openFile'],
        // filters: [{
        //   name: '*',
        //   extensions: ['graphql']
        // }]
      },
      fileNames => {
        if (fileNames && fileNames.length > 0) {
          const file = fileNames[0]
          this.openFile(file)
        }
      },
    )
  }

  getSaveFileName(): Promise<string> {
    return new Promise((resolve, reject) => {
      // save current tab

      if (this.playground) {
        const session = getSessionsState(store.getState())
        if (session.isConfigTab) {
          this.playground.handleSaveConfig()
        }

        if (session.isSettingsTab) {
          this.playground.handleSaveSettings()
        }

        if (session.isFile && session.filePath) {
          // TODO
          // dialog.showSaveDialog(
          //   {
          //     title: 'Save Permission Query',
          //     filters: [
          //       {
          //         name: 'Permission File',
          //         extensions: ['graphql'],
          //       },
          //     ],
          //   },
          //   (fileName: any) => {
          //     resolve(fileName)
          //   },
          // )
          this.props.saveFile()
          fs.writeFileSync(session.filePath, session.file)
        }

        this.playground.handleSaveConfig()
      }
    })
  }

  saveConfig = (configString: string) => {
    fs.writeFileSync(this.state.configPath, configString)
    this.setState({ configString })
  }

  // async saveFile() {
  //   const session = this.playground.state.sessions[
  //     this.playground.state.selectedSessionIndex
  //   ]
  //   ;(this.playground as any).setValueInSession(session.id, 'hasChanged', false)
  //   const fileName =
  //     (session as any).absolutePath || (await this.getSaveFileName())
  //   // if (!(session as any).absolutePath) {
  //   ;(this.playground as any).setValueInSession(
  //     session.id,
  //     'name',
  //     path.basename(fileName),
  //   )
  //   ;(this.playground as any).setValueInSession(
  //     session.id,
  //     'absolutePath',
  //     fileName,
  //   )
  //   // }
  //   const query = session.query
  //   fs.writeFileSync(fileName, query)
  // }

  getGraphcoolYml(from: string): { ymlPath: string; yml: any } | null {
    const ymlPath = findUp.sync('graphcool.yml', { cwd: from })
    if (ymlPath) {
      const file = fs.readFileSync(ymlPath)
      try {
        return {
          yml: yaml.safeLoad(file),
          ymlPath,
        }
      } catch (e) {
        // console.error(e)
      }
    }

    return null
  }

  getGraphcoolRc(): any | null {
    const graphcoolRc = path.join(os.homedir(), '.graphcoolrc')
    if (fs.existsSync(graphcoolRc)) {
      const file = fs.readFileSync(graphcoolRc)
      try {
        return yaml.safeLoad(file)
      } catch (e) {
        // console.error(e)
      }
    }

    return null
  }

  readTabMessage = (error, message) => {
    switch (message) {
      case 'Next':
        this.nextTab()
        break
      case 'Prev':
        this.prevTab()
        break
      case 'New':
        this.newTab()
        break
      case 'Close':
        if (!this.state.endpoint && !this.state.config) {
          ipcRenderer.send(
            'CloseWindow',
            JSON.stringify({ id: remote.getCurrentWindow().id }),
          )
        } else {
          this.closeTab()
        }
        break
      case 'Settings':
        this.openSettingsTab()
        break
      case 'ReloadSchema':
        this.reloadSchema()
        break
    }
  }

  render() {
    const { theme, endpoint, platformToken, configString, config } = this.state

    return (
      <div
        className={
          'flex flexColumn bgDarkestBlue overflowHidden ' +
          cx('root', theme, { noConfig: !configString })
        }
      >
        <style jsx={true} global={true}>{`
          .app-content .left-content {
            letter-spacing: 0.5px;
          }
          body .root.noConfig .tabs {
            padding-left: 80px;
          }
        `}</style>
        <style jsx={true}>{`
          .root {
            @p: .flex, .flexColumn, .bgDarkestBlue, .overflowHidden;
          }
          .root.light {
            background-color: #dbdee0;
          }
          .app-content .playground {
            @p: .flex1;
          }
          .light .sidenav-footer {
            background-color: #eeeff0;
          }
          .sidenav-footer .button {
            @p: .br2, .black90, .pointer, .pa10, .fw6, .flex, .itemsCenter,
              .ml20;
          }
        `}</style>
        <InitialView
          isOpen={!endpoint && !configString}
          onSelectFolder={this.handleSelectFolder}
          onSelectEndpoint={this.handleSelectEndpoint}
          selectHistory={this.handleSelectItem}
        />
        {(endpoint || configString) && (
          <div className="playground">
            <Playground
              getRef={this.setRef}
              endpoint={endpoint}
              isElectron={true}
              platformToken={platformToken}
              configString={configString}
              config={config}
              configPath={this.state.configPath}
              onSaveConfig={this.saveConfig}
              canSaveConfig={true}
              env={this.state.env}
              folderName={this.state.folderName}
              showNewWorkspace={true}
              onNewWorkspace={this.handleOpenNewWindow}
            />
          </div>
        )}
      </div>
    )
  }

  private handleSelectItem = ({ type, ...item }) => {
    this.setState(item as any)
    this.props.selectAppHistoryItem(set(item, 'lastOpened', new Date()) as any)
  }

  private setRef = ref => {
    this.playground = ref
  }
}

const mapStateToProps = createStructuredSelector({
  endpoint: getEndpoint,
})

export default connect(
  mapStateToProps,
  {
    openSettingsTab,
    selectNextTab,
    selectPrevTab,
    closeSelectedTab,
    refetchSchema,
    newSession,
    saveFile,
    newFileTab,
    selectAppHistoryItem,
  },
)(App)


================================================
FILE: packages/graphql-playground-electron/src/renderer/components/InitialView/InitialView.tsx
================================================
import * as React from 'react'
import * as isURL from 'validator/lib/isURL'
import { remote } from 'electron'
import { existsSync } from 'fs'
import { resolve } from 'path'
import { Icon, $v } from 'graphcool-styles'
import Modal from 'graphcool-ui/lib/Modal'
import { connect } from 'react-redux'
import * as format from 'date-fns/format'
import Toggle from './Toggle'
import { examples } from './data'
import { getAppHistory, AppHistoryItem } from 'graphql-playground-react'
import { createStructuredSelector, createSelector } from 'reselect'
import { OrderedMap } from 'immutable'

interface StateFromProps {
  history: OrderedMap<string, AppHistoryItem>
}

interface State {
  endpoint: string
  selectedMode: string
}

export interface Props {
  isOpen: boolean
  onSelectEndpoint: (endpoint: string) => void
  onSelectFolder: (config: string) => void
  selectHistory: (history: AppHistoryItem) => any
}

const modalStyle = {
  overlay: {
    zIndex: 20,
    backgroundColor: 'rgba(15,32,46,.9)',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
    '-webkit-app-region': 'drag',
  },
  content: {
    position: 'relative',
    width: 976,
    height: 'auto',
    top: 'initial',
    left: 'initial',
    right: 'initial',
    bottom: 'initial',
    borderRadius: 2,
    padding: 0,
    border: 'none',
    background: 'none',
    boxShadow: '0 1px 7px rgba(0,0,0,.2)',
  },
}

class InitialView extends React.Component<Props & StateFromProps, State> {
  state = {
    endpoint: '',
    selectedMode: 'local',
  }

  handleRequestClose = () => null

  handleSubmit = e => {
    e.preventDefault()
    if (isURL(this.state.endpoint, { require_tld: false })) {
      this.props.selectHistory(
        new AppHistoryItem({
          type: 'endpoint',
          path: this.state.endpoint,
        }),
      )
      this.props.onSelectEndpoint(this.state.endpoint)
    } else {
      alert('Endpoint is not a valid url')
    }
  }

  handleClickLocal = () => {
    const paths = remote.dialog.showOpenDialog({
      properties: ['openDirectory'],
    })
    if (paths && paths[0]) {
      const path = paths[0]
      // Check if there is a .graphqlconfig file in the folder
      if (
        !existsSync(resolve(path, '.graphqlconfig')) &&
        !existsSync(resolve(path, '.graphqlconfig.yml')) &&
        !existsSync(resolve(path, '.graphqlconfig.yaml'))
      ) {
        alert('No .graphqlconfig found in this folder')
        return
      }
      this.setState({ endpoint: path } as State)
      this.props.onSelectFolder(path)
    }
  }

  handleChangeEndpoint = e => {
    this.setState({ endpoint: e.target.value } as State)
  }

  handleChangeMode = selectedMode => {
    this.setState({ selectedMode } as State)
  }

  handleClickHistory = (history: AppHistoryItem) => {
    this.props.selectHistory(history)
  }

  render() {
    const { isOpen, history } = this.props
    const { endpoint, selectedMode } = this.state
    const choicesMode = ['local', 'url endpoint']
    const items = history.toJS()

    return (
      <div>
        <style jsx={true}>{`
          .initial-view-content {
            @p: .bgWhite, .flex, .flexRow;
          }
          .initial-view-recent {
            @p: .br, .bBlack10, .overflowHidden, .flex, .flexColumn;
            flex: 0 30%;
            max-height: 350px;
          }
          .initial-view-recent-header {
            @p: .pv10, .ph20, .bgBlack07, .black50, .bb, .bBlack10;
          }
          .initial-view-recent-list {
            @p: .flex1;
            overflow: auto;
          }
          .list-item {
            @p: .pv10, .ph20, .bb, .bBlack10, .pointer;
          }
          .list-item-name {
            @p: .f20, .black70, .fw6, .mb6, .toe, .overflowHidden, .nowrap;
          }
          .list-item-date {
            @p: .f12, .black40, .flex;
          }
          .list-item-date span {
            @p: .ml10;
          }
          .initial-view-workspace {
            @p: .flex1, .tc, .pv20;
          }
          .initial-view-workspace .title {
            @p: .maAuto, .black90;
          }
          .initial-view-workspace .description {
            @p: .maAuto, .black50, .mt16;
            max-width: 266px;
            margin-bottom: 80px !important;
          }
          .initial-view-workspace .toggle {
            @p: .justifyCenter, .flex;
          }
          .initial-view-workspace .container-input {
            @p: .ph10, .pv6, .mh38, .mt20, .darkBlue40, .ba, .bBlack10, .br2,
              .flex, .f14;
          }
          .initial-view-workspace .container-input input {
            @p: .darkBlue60, .w100, .f14;
          }
          .initial-view-workspace .container-input button {
            @p: .white, .br2, .pv6, .ph10, .pointer, .f14, .fw6;
            letter-spacing: 0.53px;
            background-color: #2a7ed3;
          }
        `}</style>
        <div className="dragable" />
        <Modal
          isOpen={isOpen}
          contentLabel="initial view"
          onRequestClose={this.handleRequestClose}
          style={modalStyle}
        >
          <div className="initial-view-content bgWhite flex flexRow">
            {history.size > 0 ? (
              <div className="initial-view-recent br bBlack10 overflowHidden flex flexColumn">
                <div className="initial-view-recent-header pv10 ph20 bgBlack07 black50 bb bBlack10">
                  RECENT
                </div>
                <div className="initial-view-recent-list flex1">
                  {Object.keys(items)
                    .reverse()
                    .map((key) => {
                      const data = items[key]
                      const name = data.folderName || data.endpoint || data.path
                      return (
                        <div
                          className="list-item pv10 ph20 bb bBlack10 pointer"
                          // tslint:disable-next-line
                          onClick={() => this.handleClickHistory(data)}
                        >
                          <div
                            className="list-item-name f20 black70 fw6 mb6 toe overflowHidden nowrap"
                            title={name}
                          >
                            {name}
                          </div>
                          <div className="list-item-date f12 black40 flex">
                            <Icon
                              src={
                                data.type === 'local'
                                  ? require('../../icons/folder.svg')
                                  : require('graphcool-styles/icons/fill/world.svg')
                              }
                              color={$v.gray40}
                              width={14}
                              height={14}
                            />
                            <span>
                              Last opened{' '}
                              {format(data.lastOpened, 'DD.MM.YYYY')}
                            </span>
                          </div>
                        </div>
                      )
                    })}
                </div>
              </div>
            ) : (
              <div className="initial-view-recent br bBlack10 overflowHidden flex flexColumn">
                <div className="initial-view-recent-header pv10 ph20 bgBlack07 black50 bb bBlack10">
                  EXAMPLES
                </div>
                <div className="initial-view-recent-list flex1">
                  {examples.map((example) => (
                    <div
                      key={example.endpoint}
                      className="list-item pv10 ph20 bb bBlack10 pointer"
                      onClick={() =>
                        this.props.onSelectEndpoint(example.endpoint)
                      }
                    >
                      <div
                        className="list-item-name f20 black70 fw6 mb6 toe overflowHidden nowrap"
                        title={example.endpoint}
                      >
                        {example.name}
                      </div>
                      <div className="list-item-date f12 black40 flex">
                        <Icon
                          src={require('graphcool-styles/icons/fill/world.svg')}
                          color={$v.gray40}
                          width={14}
                          height={14}
                        />
                        <span>{example.endpoint}</span>
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            )}
            <div className="initial-view-workspace flex1 tc pv20">
              <h1 className="title flex1 tc pv20">New Workspace</h1>
              <p className="description maAuto black50 mt16">
                Either load a local repository with a .graphqlconfig file, or
                just open a HTTP endpoint
              </p>
              <div className="toggle justifyCenter flex">
                <Toggle
                  choices={choicesMode}
                  activeChoice={selectedMode}
                  onChange={this.handleChangeMode}
                />
              </div>
              {selectedMode === 'url endpoint' && (
                <form
                  className="container-input ph10 pv6 mh38 mt20 darkBlue40 ba bBlack10 br2 flex f14"
                  onSubmit={this.handleSubmit}
                >
                  <input
                    className="input darkBlue60 w100 f14"
                    placeholder="Enter endpoint url..."
                    value={endpoint}
                    onChange={this.handleChangeEndpoint}
                  />
                  <button className="white br2 pv6 ph10 pointer f14 fw6">
                    OPEN
                  </button>
                </form>
              )}
              {selectedMode === 'local' && (
                <div
                  className="container-input ph10 pv6 mh38 mt20 darkBlue40 ba bBlack10 br2 flex f14"
                  onClick={this.handleClickLocal}
                >
                  <input
                    className="input darkBlue60 w100 f14"
                    placeholder="Select a folder..."
                    value={endpoint}
                    onChange={this.handleChangeEndpoint}
                  />
                  <button className="white br2 pv6 ph10 pointer f14 fw6">
                    OPEN
                  </button>
                </div>
              )}
            </div>
          </div>
        </Modal>
      </div>
    )
  }
}

const itemsSelector = createSelector([getAppHistory], state => state.items)

const mapStateToProps = createStructuredSelector({
  history: itemsSelector,
})

export default connect(mapStateToProps)(InitialView as any) as any


================================================
FILE: packages/graphql-playground-electron/src/renderer/components/InitialView/Toggle.tsx
================================================
import * as React from 'react'
import * as cn from 'classnames'

export interface ToggleProps {
  choices: string[]
  onChange: (choice: string, i: number) => void
  activeChoice: string
}

/* tslint:disable */
const Toggle = ({ choices, onChange, activeChoice }: ToggleProps) => {
  return (
    <div className="toggle flex">
      <style jsx={true}>{`
        .toggle {
          @p: .flex;
        }
        .choice {
          @p: .f14, .ttu, .br2, .mr6, .fw6, .darkBlue40, .pointer;
          letter-spacing: 0.53px;
          padding: 5px 9px;
        }
        .choice.active {
          @p: .darkBlue50, .bgDarkBlue10;
        }
        .choice:not(.active):hover {
          @p: .darkBlue50;
        }
      `}</style>
      {choices.map((choice, i) => (
        <div
          className={
            'f14 ttu br2 mr6 fw6 darkBlue40 pointer ' +
            cn('choice', {
              'active darkBlue50 bgDarkBlue10': choice === activeChoice,
            })
          }
          key={choice}
          onClick={() => onChange(choice, i)}
        >
          {choice}
        </div>
      ))}
    </div>
  )
}

export default Toggle


================================================
FILE: packages/graphql-playground-electron/src/renderer/components/InitialView/data.ts
================================================
export const examples = [
  {
    name: 'Movie Database',
    endpoint: 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr',
  },
  {
    name: 'Instagram',
    endpoint: 'https://api.graph.cool/simple/v1/cixne4sn40c7m0122h8fabni1',
  },
  {
    name: 'Pokemon',
    endpoint: 'https://graphql-pokemon.now.sh',
  },
]


================================================
FILE: packages/graphql-playground-electron/src/renderer/components/Loading.tsx
================================================
import * as React from 'react'

interface Props {
  color?: string
  width?: number
  height?: number
  className?: string
}

export default class Loading extends React.Component<Props, {}> {
  render() {
    const width = this.props.width || 30
    const height = this.props.height || 30
    const backgroundColor = this.props.color || '#000'
    return (
      <div
        style={{ width, height, backgroundColor }}
        className={`root ${this.props.className}`}
      >
        <style jsx={true}>{`
          div {
            border-radius: 100%;
            animation: sk-scaleout 1s infinite ease-in-out;
          }

          @keyframes sk-scaleout {
            0% {
              transform: scale(0);
            }
            100% {
              transform: scale(1);
              opacity: 0;
            }
          }
        `}</style>
      </div>
    )
  }
}


================================================
FILE: packages/graphql-playground-electron/src/renderer/components/Root.tsx
================================================
import * as React from 'react'
import App from './App'
import { store } from 'graphql-playground-react'
import { Provider } from 'react-redux'

export default class Root extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <App />
      </Provider>
    )
  }
}


================================================
FILE: packages/graphql-playground-electron/src/renderer/index.css
================================================
body {
    overflow: hidden;
}

================================================
FILE: packages/graphql-playground-electron/src/renderer/index.html
================================================
<!DOCTYPE html>
<html>

<head>
  <meta charset=utf-8 />
  <meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
  <title>GraphQL Playground</title>
  <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700|Source+Code+Pro:400,500,700" rel="stylesheet">

</head>

<body>
  <style type="text/css">
    html {
      font-family: "Open Sans", sans-serif;
      overflow: hidden;
    }

    body {
      margin: 0;
      background: #172a3a;
    }

    .playgroundIn {
      -webkit-animation: playgroundIn 0.5s ease-out forwards;
      animation: playgroundIn 0.5s ease-out forwards;
    }

    @-webkit-keyframes playgroundIn {
      from {
        opacity: 0;
        -webkit-transform: translateY(10px);
        -ms-transform: translateY(10px);
        transform: translateY(10px);
      }
      to {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
    }

    @keyframes playgroundIn {
      from {
        opacity: 0;
        -webkit-transform: translateY(10px);
        -ms-transform: translateY(10px);
        transform: translateY(10px);
      }
      to {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
    }
  </style>

  <style type="text/css">
    .fadeOut {
      -webkit-animation: fadeOut 0.5s ease-out forwards;
      animation: fadeOut 0.5s ease-out forwards;
    }

    @-webkit-keyframes fadeIn {
      from {
        opacity: 0;
        -webkit-transform: translateY(-10px);
        -ms-transform: translateY(-10px);
        transform: translateY(-10px);
      }
      to {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
    }

    @keyframes fadeIn {
      from {
        opacity: 0;
        -webkit-transform: translateY(-10px);
        -ms-transform: translateY(-10px);
        transform: translateY(-10px);
      }
      to {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
    }

    @-webkit-keyframes fadeOut {
      from {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
      to {
        opacity: 0;
        -webkit-transform: translateY(-10px);
        -ms-transform: translateY(-10px);
        transform: translateY(-10px);
      }
    }

    @keyframes fadeOut {
      from {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
      to {
        opacity: 0;
        -webkit-transform: translateY(-10px);
        -ms-transform: translateY(-10px);
        transform: translateY(-10px);
      }
    }

    @-webkit-keyframes appearIn {
      from {
        opacity: 0;
        -webkit-transform: translateY(0px);
        -ms-transform: translateY(0px);
        transform: translateY(0px);
      }
      to {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
    }

    @keyframes appearIn {
      from {
        opacity: 0;
        -webkit-transform: translateY(0px);
        -ms-transform: translateY(0px);
        transform: translateY(0px);
      }
      to {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
    }

    @-webkit-keyframes scaleIn {
      from {
        -webkit-transform: scale(0);
        -ms-transform: scale(0);
        transform: scale(0);
      }
      to {
        -webkit-transform: scale(1);
        -ms-transform: scale(1);
        transform: scale(1);
      }
    }

    @keyframes scaleIn {
      from {
        -webkit-transform: scale(0);
        -ms-transform: scale(0);
        transform: scale(0);
      }
      to {
        -webkit-transform: scale(1);
        -ms-transform: scale(1);
        transform: scale(1);
      }
    }

    @-webkit-keyframes innerDrawIn {
      0% {
        stroke-dashoffset: 70;
      }
      50% {
        stroke-dashoffset: 140;
      }
      100% {
        stroke-dashoffset: 210;
      }
    }

    @keyframes innerDrawIn {
      0% {
        stroke-dashoffset: 70;
      }
      50% {
        stroke-dashoffset: 140;
      }
      100% {
        stroke-dashoffset: 210;
      }
    }

    @-webkit-keyframes outerDrawIn {
      0% {
        stroke-dashoffset: 76;
      }
      100% {
        stroke-dashoffset: 152;
      }
    }

    @keyframes outerDrawIn {
      0% {
        stroke-dashoffset: 76;
      }
      100% {
        stroke-dashoffset: 152;
      }
    }

    .hHWjkv {
      -webkit-transform-origin: 0px 0px;
      -ms-transform-origin: 0px 0px;
      transform-origin: 0px 0px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;
      animation: scaleIn 0.25s linear forwards 0.2222222222222222s;
    }

    .gCDOzd {
      -webkit-transform-origin: 0px 0px;
      -ms-transform-origin: 0px 0px;
      transform-origin: 0px 0px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;
      animation: scaleIn 0.25s linear forwards 0.4222222222222222s;
    }

    .hmCcxi {
      -webkit-transform-origin: 0px 0px;
      -ms-transform-origin: 0px 0px;
      transform-origin: 0px 0px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;
      animation: scaleIn 0.25s linear forwards 0.6222222222222222s;
    }

    .eHamQi {
      -webkit-transform-origin: 0px 0px;
      -ms-transform-origin: 0px 0px;
      transform-origin: 0px 0px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;
      animation: scaleIn 0.25s linear forwards 0.8222222222222223s;
    }

    .byhgGu {
      -webkit-transform-origin: 0px 0px;
      -ms-transform-origin: 0px 0px;
      transform-origin: 0px 0px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;
      animation: scaleIn 0.25s linear forwards 1.0222222222222221s;
    }

    .llAKP {
      -webkit-transform-origin: 0px 0px;
      -ms-transform-origin: 0px 0px;
      transform-origin: 0px 0px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;
      animation: scaleIn 0.25s linear forwards 1.2222222222222223s;
    }

    .bglIGM {
      -webkit-transform-origin: 64px 28px;
      -ms-transform-origin: 64px 28px;
      transform-origin: 64px 28px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;
      animation: scaleIn 0.25s linear forwards 0.2222222222222222s;
    }

    .ksxRII {
      -webkit-transform-origin: 95.98500061035156px 46.510000228881836px;
      -ms-transform-origin: 95.98500061035156px 46.510000228881836px;
      transform-origin: 95.98500061035156px 46.510000228881836px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;
      animation: scaleIn 0.25s linear forwards 0.4222222222222222s;
    }

    .cWrBmb {
      -webkit-transform-origin: 95.97162628173828px 83.4900016784668px;
      -ms-transform-origin: 95.97162628173828px 83.4900016784668px;
      transform-origin: 95.97162628173828px 83.4900016784668px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;
      animation: scaleIn 0.25s linear forwards 0.6222222222222222s;
    }

    .Wnusb {
      -webkit-transform-origin: 64px 101.97999572753906px;
      -ms-transform-origin: 64px 101.97999572753906px;
      transform-origin: 64px 101.97999572753906px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;
      animation: scaleIn 0.25s linear forwards 0.8222222222222223s;
    }

    .bfPqf {
      -webkit-transform-origin: 32.03982162475586px 83.4900016784668px;
      -ms-transform-origin: 32.03982162475586px 83.4900016784668px;
      transform-origin: 32.03982162475586px 83.4900016784668px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;
      animation: scaleIn 0.25s linear forwards 1.0222222222222221s;
    }

    .edRCTN {
      -webkit-transform-origin: 32.033552169799805px 46.510000228881836px;
      -ms-transform-origin: 32.033552169799805px 46.510000228881836px;
      transform-origin: 32.033552169799805px 46.510000228881836px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;
      animation: scaleIn 0.25s linear forwards 1.2222222222222223s;
    }

    .iEGVWn {
      opacity: 0;
      stroke-dasharray: 76;
      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;
      animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;
      -webkit-animation-iteration-count: 1, 1;
      animation-iteration-count: 1, 1;
    }

    .bsocdx {
      opacity: 0;
      stroke-dasharray: 76;
      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;
      animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;
      -webkit-animation-iteration-count: 1, 1;
      animation-iteration-count: 1, 1;
    }

    .jAZXmP {
      opacity: 0;
      stroke-dasharray: 76;
      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;
      animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;
      -webkit-animation-iteration-count: 1, 1;
      animation-iteration-count: 1, 1;
    }

    .hSeArx {
      opacity: 0;
      stroke-dasharray: 76;
      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;
      animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;
      -webkit-animation-iteration-count: 1, 1;
      animation-iteration-count: 1, 1;
    }

    .bVgqGk {
      opacity: 0;
      stroke-dasharray: 76;
      -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;
      animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;
      -webkit-animation-iteration-count: 1, 1;
      animation-iteration-count: 1, 1;
    }

    .hEFqBt {
      opacity: 0;
      stroke-dasharray: 76;
      -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;
      animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;
      -webkit-animation-iteration-count: 1, 1;
      animation-iteration-count: 1, 1;
    }

    .dzEKCM {
      opacity: 0;
      stroke-dasharray: 70;
      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;
      animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;
      -webkit-animation-iteration-count: infinite, 1;
      animation-iteration-count: infinite, 1;
    }

    .DYnPx {
      opacity: 0;
      stroke-dasharray: 70;
      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;
      animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;
      -webkit-animation-iteration-count: infinite, 1;
      animation-iteration-count: infinite, 1;
    }

    .hjPEAQ {
      opacity: 0;
      stroke-dasharray: 70;
      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;
      animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;
      -webkit-animation-iteration-count: infinite, 1;
      animation-iteration-count: infinite, 1;
    }

    #loading-wrapper {
      position: absolute;
      width: 100vw;
      height: 100vh;
      display: -webkit-box;
      display: -webkit-flex;
      display: -ms-flexbox;
      display: flex;
      -webkit-align-items: center;
      -webkit-box-align: center;
      -ms-flex-align: center;
      align-items: center;
      -webkit-box-pack: center;
      -webkit-justify-content: center;
      -ms-flex-pack: center;
      justify-content: center;
      -webkit-flex-direction: column;
      -ms-flex-direction: column;
      flex-direction: column;
    }

    .logo {
      width: 75px;
      height: 75px;
      margin-bottom: 20px;
      opacity: 0;
      -webkit-animation: fadeIn 0.5s ease-out forwards;
      animation: fadeIn 0.5s ease-out forwards;
    }

    .text {
      font-size: 32px;
      font-weight: 200;
      text-align: center;
      color: rgba(255, 255, 255, 0.6);
      opacity: 0;
      -webkit-animation: fadeIn 0.5s ease-out forwards;
      animation: fadeIn 0.5s ease-out forwards;
    }

    .dGfHfc {
      font-weight: 400;
    }
  </style>
  <div id="loading-wrapper">
    <svg class="logo" viewBox="0 0 128 128" xmlns:xlink="http://www.w3.org/1999/xlink">
      <title>GraphQL Playground Logo</title>
      <defs>
        <linearGradient id="linearGradient-1" x1="4.86%" x2="96.21%" y1="0%" y2="99.66%">
          <stop stop-color="#E00082" stop-opacity=".8" offset="0%"></stop>
          <stop stop-color="#E00082" offset="100%"></stop>
        </linearGradient>
      </defs>
      <g>
        <rect id="Gradient" width="127.96" height="127.96" y="1" fill="url(#linearGradient-1)" rx="4"></rect>
        <path id="Border" fill="#E00082" fill-rule="nonzero" d="M4.7 2.84c-1.58 0-2.86 1.28-2.86 2.85v116.57c0 1.57 1.28 2.84 2.85 2.84h116.57c1.57 0 2.84-1.26 2.84-2.83V5.67c0-1.55-1.26-2.83-2.83-2.83H4.67zM4.7 0h116.58c3.14 0 5.68 2.55 5.68 5.7v116.58c0 3.14-2.54 5.68-5.68 5.68H4.68c-3.13 0-5.68-2.54-5.68-5.68V5.68C-1 2.56 1.55 0 4.7 0z"></path>
        <path class="bglIGM" x="64" y="28" fill="#fff" d="M64 36c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8" style="transform: translate(100px, 100px);"></path>
        <path class="ksxRII" x="95.98500061035156" y="46.510000228881836" fill="#fff" d="M89.04 50.52c-2.2-3.84-.9-8.73 2.94-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.76.9-10.97-2.94"
          style="transform: translate(100px, 100px);"></path>
        <path class="cWrBmb" x="95.97162628173828" y="83.4900016784668" fill="#fff" d="M102.9 87.5c-2.2 3.84-7.1 5.15-10.94 2.94-3.84-2.2-5.14-7.12-2.94-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.86 2.23 5.16 7.12 2.94 10.96"
          style="transform: translate(100px, 100px);"></path>
        <path class="Wnusb" x="64" y="101.97999572753906" fill="#fff" d="M64 110c-4.43 0-8-3.6-8-8.02 0-4.44 3.57-8.02 8-8.02s8 3.58 8 8.02c0 4.4-3.57 8.02-8 8.02"
          style="transform: translate(100px, 100px);"></path>
        <path class="bfPqf" x="32.03982162475586" y="83.4900016784668" fill="#fff" d="M25.1 87.5c-2.2-3.84-.9-8.73 2.93-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.74.9-10.95-2.94"
          style="transform: translate(100px, 100px);"></path>
        <path class="edRCTN" x="32.033552169799805" y="46.510000228881836" fill="#fff" d="M38.96 50.52c-2.2 3.84-7.12 5.15-10.95 2.94-3.82-2.2-5.12-7.12-2.92-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.83 2.23 5.14 7.12 2.94 10.96"
          style="transform: translate(100px, 100px);"></path>
        <path class="iEGVWn" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M63.55 27.5l32.9 19-32.9-19z"></path>
        <path class="bsocdx" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M96 46v38-38z"></path>
        <path class="jAZXmP" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M96.45 84.5l-32.9 19 32.9-19z"></path>
        <path class="hSeArx" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M64.45 103.5l-32.9-19 32.9 19z"></path>
        <path class="bVgqGk" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M32 84V46v38z"></path>
        <path class="hEFqBt" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M31.55 46.5l32.9-19-32.9 19z"></path>
        <path class="dzEKCM" id="Triangle-Bottom" stroke="#fff" stroke-width="4" d="M30 84h70" stroke-linecap="round"></path>
        <path class="DYnPx" id="Triangle-Left" stroke="#fff" stroke-width="4" d="M65 26L30 87" stroke-linecap="round"></path>
        <path class="hjPEAQ" id="Triangle-Right" stroke="#fff" stroke-width="4" d="M98 87L63 26" stroke-linecap="round"></path>
      </g>
    </svg>
    <div class="text">Loading
      <span class="dGfHfc">GraphQL Playground</span>
    </div>
  </div>

  <div id="root" />
  <script type="text/javascript">
    window.addEventListener('load', function (event) {
      const loadingWrapper = document.getElementById('loading-wrapper');
      if (loadingWrapper) {
        loadingWrapper.classList.add('fadeOut');
      }

      const root = document.getElementById('root');
      root.classList.add('playgroundIn');
    })
  </script>
</body>

</html>

================================================
FILE: packages/graphql-playground-electron/src/renderer/index.tsx
================================================
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import Root from './components/Root'
import 'graphcool-styles/dist/styles.css'
import './index.css'

ReactDOM.render(<Root />, document.getElementById('root'))


================================================
FILE: packages/graphql-playground-electron/src/renderer/redux/actions/history.ts
================================================
export type SELECT_HISTORY = 'select history'
export const SELECT_HISTORY: SELECT_HISTORY = 'select history'

export interface SelectHistoryAction {
  type: SELECT_HISTORY
  history: History
}

export interface History {
  type: 'local' | 'endpoint'
  path: string
  lastOpened?: Date
}

export const selectHistory = (history: History): SelectHistoryAction => ({
  type: SELECT_HISTORY,
  history,
})


================================================
FILE: packages/graphql-playground-electron/src/renderer/redux/createStore.ts
================================================
import { compose, createStore } from 'redux'
import persistState, { mergePersistedState } from 'redux-localstorage'
import filter from 'redux-localstorage-filter'
import * as adapter from 'redux-localstorage/lib/adapters/localStorage'
import { merge } from 'lodash'
import combinedReducers from './reducers'

let localStorage: any = null

if (typeof window !== 'undefined') {
  localStorage = window.localStorage
} else {
  localStorage = {
    clearItem: () => null,
    getItem: () => null,
    setItem: () => null,
  }
}

const composeEnhancers = compose

const storage = composeEnhancers(filter(['history.history']))(
  adapter(localStorage),
)

const reducer = composeEnhancers(
  mergePersistedState((initialState, persistedState) => {
    return merge({}, initialState, persistedState)
  }),
)(combinedReducers)

const enhancer = composeEnhancers(
  persistState(storage, 'graphql-playground-electron'),
)

const functions = [enhancer]
//
// if (window.__REDUX_DEVTOOLS_EXTENSION__) {
//   functions.push(window.__REDUX_DEVTOOLS_EXTENSION__())
// }

export default () =>
  createStore(reducer, composeEnhancers.apply(null, functions))


================================================
FILE: packages/graphql-playground-electron/src/renderer/redux/reducers/history.ts
================================================
import {
  SELECT_HISTORY,
  SelectHistoryAction,
  History,
} from '../actions/history'

export type HistoryAction = SelectHistoryAction

export interface State {
  readonly history: History[]
}

const defaultState: State = {
  history: [],
}

export default function historyReducer(
  state: State = defaultState,
  action: HistoryAction,
): State {
  switch (action.type) {
    case SELECT_HISTORY:
      const { history } = action
      history.lastOpened = new Date()
      // See if already in list
      const index = state.history.findIndex(data => data.path === history.path)
      let newHistory = state.history
      if (index !== -1) {
        newHistory[index] = history
      } else {
        newHistory = [...state.history, history]
      }
      // Sort by date
      newHistory.sort(
        (a, b) => (new Date(a.lastOpened) < new Date(b.lastOpened) ? -1 : 1),
      )
      return {
        ...state,
        history: newHistory,
      }
  }
  return state
}


================================================
FILE: packages/graphql-playground-electron/src/renderer/redux/reducers/index.ts
================================================
import { combineReducers } from 'redux'
import graphiqlDocs from 'graphql-playground-react/lib/reducers/graphiql-docs'
import history from './history'

const combinedReducers = combineReducers({
  graphiqlDocs,
  history,
})

export default combinedReducers


================================================
FILE: packages/graphql-playground-electron/src/renderer/utils/errify.ts
================================================
import swal from 'sweetalert2'

export function errify(error: Error | string) {
  const message = typeof error === 'string' ? error : error.message
  swal({
    title: 'Error',
    text: message,
    type: 'error',
    confirmButtonText: 'Ok',
  })
}


================================================
FILE: packages/graphql-playground-electron/src/shared/utils.ts
================================================
import { remote } from 'electron'
import * as dev from 'electron-is-dev'
import * as path from 'path'

export const newWindowConfig: Electron.BrowserWindowConstructorOptions = {
  title: 'GraphQL Playground',
  width: 1200,
  height: 800,
  titleBarStyle: 'hiddenInset',
  icon: path.join(__dirname, '../static/icons/icon.icns'),
  backgroundColor: '#0F202D',
}

export function createRemoteWindow() {
  const win = new remote.BrowserWindow(newWindowConfig)
  const url = dev
    ? 'http://localhost:4040'
    : `file://${path.join(__dirname, '..', '/dist/index.html')}`

  win.loadURL(url)
}


================================================
FILE: packages/graphql-playground-electron/tsconfig.json
================================================
{
  "compilerOptions": {
    "removeComments": true,
    "module": "commonjs",
    "jsx": "react",
    "sourceMap": true,
    "target": "esnext",
    "moduleResolution": "node",
    "allowJs": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "lib": ["es2015", "dom"],
    "outDir": "lib",
    "baseUrl": "./",
    "skipDefaultLibCheck": true,
    "skipLibCheck": true
  },
  "exclude": ["node_modules", "dist", "lib"],
  "include": ["typings/custom.d.ts", "typings/styled-jsx.d.ts"],
  "files": ["src/renderer/index.tsx", "src/main/index.ts"]
}


================================================
FILE: packages/graphql-playground-electron/tslint.json
================================================
{
  "extends": [
    "tslint-graphcool-frontend"
  ],
  "rules": {
    "no-console": false,
    "no-implicit-dependencies": false,
    "no-submodule-imports": false,
    "jsx-no-lambda": false
  }
}


================================================
FILE: packages/graphql-playground-electron/typings/custom.d.ts
================================================
interface Window {
  GraphQLPlayground: any
  __REDUX_DEVTOOLS_EXTENSION__: any
  __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: any
}


================================================
FILE: packages/graphql-playground-electron/typings/styled-jsx.d.ts
================================================
import 'react'

declare module 'react' {
  interface HTMLProps<T> {
    jsx?: boolean
    global?: boolean
  }
}

declare module 'react' {
  interface StyleHTMLAttributes<T> extends React.HTMLAttributes<T> {
    jsx?: boolean
    global?: boolean
  }
}


================================================
FILE: packages/graphql-playground-electron/webpack.config.build.js
================================================
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const cssnano = require('cssnano')
const path = require('path')
const config = require('./webpack.config')
const HappyPack = require('happypack')
const os = require('os')
const fs = require('fs')
const UglifyJSParallelPlugin = require('webpack-uglify-parallel')
const { renderPlaygroundPage } = require('graphql-playground-html')

const appEntrypoint = 'src/renderer/index.html'

// Create the playground entry point if it doesn't exist
if (!fs.existsSync(appEntrypoint)) {
  fs.writeFileSync(appEntrypoint, renderPlaygroundPage({ env: 'react' }))
}

module.exports = {
  devtool: 'source-map',
  mode: 'production',
  target: 'electron-renderer',
  entry: {
    app: ['./src/renderer'],
  },
  output: {
    path: __dirname + '/dist',
    filename: '[name].[hash].js',
    sourceMapFilename: '[file].map',
    publicPath: './',
  },
  node: {
    __dirname: false,
    __filename: false,
  },
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.ts(x?)$/,
        loader: 'tslint-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        loader: 'style-loader!css-loader',
      },
      {
        test: /\.scss$/,
        loader:
          'style-loader!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader!sass-loader',
      },
      {
        test: /\.ts(x?)$/,
        include: __dirname + '/src',
        use: [
          {
            loader: 'happypack/loader?id=babel',
          },
          {
            loader: 'happypack/loader?id=ts',
          },
        ],
      },
      {
        test: /\.js$/,
        loader: 'happypack/loader?id=babel',
        include: __dirname + '/src',
      },
      {
        test: /\.mp3$/,
        loader: 'file-loader',
      },
      {
        test: /icons\/.*\.svg$/,
        loader:
          'raw-loader!svgo-loader?{"plugins":[{"removeStyleElement":true}]}',
      },
      {
        test: /graphics\/.*\.svg$/,
        loader: 'file-loader',
      },
      {
        test: /.*\.(png|gif)$/,
        loader: 'file-loader',
      },
    ],
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('production'),
      },
      __EXAMPLE_ADDR__: '"https://dynamic-resources.graph.cool"',
    }),
    new HtmlWebpackPlugin({
      favicon: 'static/favicon.png',
      template: appEntrypoint,
    }),
    new webpack.optimize.OccurrenceOrderPlugin(),
    /* new UglifyJSParallelPlugin({
      workers: os.cpus().length,
      compress: {
        unused: true,
        dead_code: true,
        warnings: false,
      },
      sourceMap: false,
      mangle: false,
    }), */
    // https://github.com/graphql/graphql-language-service/issues/111
    new webpack.ContextReplacementPlugin(
      /graphql-language-service-interface[\/\\]dist/,
      /\.js$/,
    ),
    new webpack.NormalModuleReplacementPlugin(/\/iconv-loader$/, 'node-noop'),
    // new webpack.optimize.CommonsChunkPlugin('vendor'),
    new webpack.optimize.ModuleConcatenationPlugin(),
    new webpack.LoaderOptionsPlugin({
      options: {
        postcss: [
          cssnano({
            autoprefixer: {
              add: true,
              remove: true,
              browsers: ['last 2 versions'],
            },
            discardComments: {
              removeAll: true,
            },
            safe: true,
          }),
        ],
        svgo: {
          plugins: [{ removeStyleElement: true }],
        },
      },
    }),
    new HappyPack({
      id: 'ts',
      threads: 2,
      loaders: ['ts-loader?' + JSON.stringify({ happyPackMode: true })],
    }),
    new HappyPack({
      id: 'babel',
      threads: 2,
      loaders: ['babel-loader'],
    }),
  ],
  resolve: {
    modules: [path.resolve('./src'), 'node_modules'],
    extensions: ['.mjs', '.js', '.ts', '.tsx'],
  },
}


================================================
FILE: packages/graphql-playground-electron/webpack.config.js
================================================
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer')
  .BundleAnalyzerPlugin
const path = require('path')
const fs = require('fs')
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
const HappyPack = require('happypack')
const { renderPlaygroundPage } = require('graphql-playground-html')

const appEntrypoint = 'src/renderer/index.html'

// Create the playground entry point if it doesn't exist
if (!fs.existsSync(appEntrypoint)) {
  fs.writeFileSync(appEntrypoint, renderPlaygroundPage({ env: 'react' }))
}

module.exports = {
  devtool: 'cheap-module-eval-source-map',
  mode: 'development',
  entry: './src/renderer',
  target: 'electron-renderer',
  output: {
    filename: '[name].[hash].js',
    publicPath: '/'
  },
  module: {
    rules: [
      {
        enforce: 'pre',
        test: /\.ts(x?)$/,
        loader: 'tslint-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        loader: 'style-loader!css-loader',
      },
      {
        test: /\.ts(x?)$/,
        include: [__dirname + '/src'],
        use: [
          {
            loader: 'happypack/loader?id=babel',
          },
          {
            loader: 'happypack/loader?id=ts',
          },
        ],
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
      },
      {
        test: /\.mp3$/,
        loader: 'file-loader',
      },
      {
        test: /(icons|node_modules)\/.*\.svg$/,
        loader: 'raw-loader!svgo-loader',
      },
      {
        test: /graphics\/.*\.svg$/,
        loader: 'file-loader',
      },
      {
        test: /.*\.(png|gif)$/,
        loader: 'file-loader',
      },
    ],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new ForkTsCheckerWebpackPlugin({}),
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('development'),
      },
      __EXAMPLE_ADDR__: '"https://dynamic-resources.graph.cool"',
    }),
    new HtmlWebpackPlugin({
      favicon: 'static/favicon.png',
      template: 'src/renderer/index.html',
    }),
    new webpack.NormalModuleReplacementPlugin(/\/iconv-loader$/, 'node-noop'),
    // See https://github.com/graphql/graphql-language-service/issues/111
    new webpack.ContextReplacementPlugin(
      /graphql-language-service-interface[\/\\]dist/,
      /\.js$/,
    ),
    new webpack.LoaderOptionsPlugin({
      options: {
        svgo: {
          plugins: [{ removeStyleElement: true }],
        },
      },
    }),
    new HappyPack({
      id: 'ts',
      threads: 2,
      loaders: ['ts-loader?' + JSON.stringify({ happyPackMode: true })],
    }),
    new HappyPack({
      id: 'babel',
      threads: 2,
      loaders: ['babel-loader'],
    }),
    // new BundleAnalyzerPlugin(),
  ],
  resolve: {
    modules: [path.resolve('./src'), 'node_modules'],
    extensions: ['.mjs', '.js', '.ts', '.tsx'],
  },
}


================================================
FILE: packages/graphql-playground-html/.gitignore
================================================
# See http://help.github.com/ignore-files/ for more about ignoring files.

# dependencies
node_modules
example/node_modules
example/yarn.lock

# testing
/coverage

# production
/dist

# misc
.DS_Store
.env
npm-debug.log
.idea


================================================
FILE: packages/graphql-playground-html/CHANGELOG.md
================================================
# Change Log

All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [1.6.29](https://github.com/graphcool/graphql-playground/compare/graphql-playground-html@1.6.28...graphql-playground-html@1.6.29) (2020-10-20)

**Note:** Version bump only for package graphql-playground-html





## [1.6.28](https://github.com/graphcool/graphql-playground/compare/graphql-playground-html@1.6.27...graphql-playground-html@1.6.28) (2020-09-15)


### Bug Fixes

* add schema.polling* to ISettings interface. ([#1212](https://github.com/graphcool/graphql-playground/issues/1212)) ([b7e6d4d](https://github.com/graphcool/graphql-playground/commit/b7e6d4d7590766183a77910a517ea946b95f2a84))





## [1.6.27](https://github.com/graphcool/graphql-playground/compare/graphql-playground-html@1.6.26...graphql-playground-html@1.6.27) (2020-08-30)

**Note:** Version bump only for package graphql-playground-html





## [1.6.26](https://github.com/graphcool/graphql-playground/compare/graphql-playground-html@1.6.23...graphql-playground-html@1.6.26) (2020-08-30)


### Bug Fixes

* cdn url ([#1238](https://github.com/graphcool/graphql-playground/issues/1238)) ([e574bb6](https://github.com/graphcool/graphql-playground/commit/e574bb69e8adcda816fa62acc7e3adf19f31947a))
* **examples:** fix examples of reflected XSS attack ([#1256](https://github.com/graphcool/graphql-playground/issues/1256)) ([12b61b9](https://github.com/graphcool/graphql-playground/commit/12b61b9d69286b12a6ac74b12aae705e6b060f3b))





## 1.6.23 (2020-06-07)


### Bug Fixes

* hide config element 😆 ([#1224](https://github.com/graphcool/graphql-playground/issues/1224)) ([a7bdcaa](https://github.com/graphcool/graphql-playground/commit/a7bdcaa669f21603ded80bb9c59c4ab41597161a))
* rectify all versions and references ([#1223](https://github.com/graphcool/graphql-playground/issues/1223)) ([239289b](https://github.com/graphcool/graphql-playground/commit/239289b3e9da1744b23b7ef2694b1ed6370e3c16))
* X-Apollo-Tracing No Schema Issue ([#1112](https://github.com/graphcool/graphql-playground/issues/1112)) ([1ca035d](https://github.com/graphcool/graphql-playground/commit/1ca035d06f71cbe02aa8f36e7fce2095c2854ba6))
* **deps:** update deps and toolchain, move back to using yarn… ([#1191](https://github.com/graphcool/graphql-playground/issues/1191)) ([824c7a5](https://github.com/graphcool/graphql-playground/commit/824c7a57f0284f022726a8b8840aafc3e8720ccd))



## 1.8.10 (2019-02-23)



## 1.8.9 (2019-02-01)



## 1.8.7 (2019-01-28)



## 1.8.6 (2019-01-27)


### Bug Fixes

* **graphql 14:** version bump via graphql-config ([#861](https://github.com/graphcool/graphql-playground/issues/861)) ([5ea711c](https://github.com/graphcool/graphql-playground/commit/5ea711c590c1265c873324b28cd3483d3e05dc98))
* close body tag ([#833](https://github.com/graphcool/graphql-playground/issues/833)) ([3d2732d](https://github.com/graphcool/graphql-playground/commit/3d2732dbd90f71f8b48465b95c7b7b5bc8bc7a1c))



# 1.6.0 (2018-05-31)



# 1.4.0 (2018-01-15)


### Bug Fixes

* **deps:** make graphql-config a normal dep ([9e4d93e](https://github.com/graphcool/graphql-playground/commit/9e4d93e0cf7ebd3ba1806407383e071fda37cb55))
* **deps:** Remove extension dependencies ([72ce36c](https://github.com/graphcool/graphql-playground/commit/72ce36cdd96f35efefd916993a949e646c5f94b2)), closes [#493](https://github.com/graphcool/graphql-playground/issues/493)
* **deps:** Updated graphql-config-extension-graphcool ([ef83c09](https://github.com/graphcool/graphql-playground/commit/ef83c097c018a42f7ee65529d6af4ea3928a4281))



## 1.3.13 (2017-12-24)



## 1.3.12 (2017-12-24)



## 1.3.9 (2017-12-14)



## 1.3.6 (2017-12-04)



## 1.3.5 (2017-12-04)


### Features

* **middleware:** draft animated loading screen ([c082c07](https://github.com/graphcool/graphql-playground/commit/c082c07cdcfeae50dd0c43a5ae225729a91556ef))


================================================
FILE: packages/graphql-playground-html/README.md
================================================
# graphql-playground-html

> **SECURITY WARNING:** This package and all of it's dependendents had a severe XSS Reflection attack vulnerability until version `1.6.22` of this package. You must sanitize any and all user input values to `renderPlaygroundPage()` values. If you used static values in your middlewares, including ours, you were not vulnerable to the attack.

This package is being used by the GraphQL Playground middlewares.

For local development, you can `yarn link` this package, then use `yarn link graphql-playground-html` in the
middleware you want to develop.


================================================
FILE: packages/graphql-playground-html/examples/xss-attack/README.md
================================================
# GraphQL Playground HTML XSS Reflection Attack Example

This shows the simplest possible example for how one might re-create the XSS Reflection Vulnerability reported by Cure53.

Notice we force the resolution to `graphql-playground-html@1.6.20`, which is the last version susceptible. All prior versions are susceptible to the attack.

Dynamic, unsanitized input that resembles some of the configuration you see is a simple example - if url parameters, query parameters, unsanitized database text strings, etc are passed to `expressPlayground()`, `renderPlaygroundPage()` or equivalent middleware functions such as `koaPlayground()`, they are all vulnerable to this attack.

## Reccomendations

Here we use `xss` because it was easy to provide for node.js, however [DOMPurify](https://github.com/cure53/DOMPurify) is also an excellent choice for sanitizing strings for unwanted html. By default it requires the browser DOM, but you can load it with JSDOM for server side purposes as well.

here are a few more tips to prevent other XSS vulnerabilities that might exist in your own applications:

- `DOMPurify.sanitize` url values with user input to be used for rendering `<a href=` or `<script src=`, `<img src=` etc. whether using react or not!
- in react,`dangerouslySetInnerHtml={{ __html: { DOMPurify.sanitize(userInputString) }}` always!
- when doing direct dom manipulation, avoid `domElement.innerHTML = string` at all costs, but at least `DOMPurify.sanitize(string)` first if you must
- when generating an entire html file, sanitize *all* user input values (this was our mistake)

## Setup

```sh
$ yarn
$ yarn start
```

## Examples

Now that you've set up the example, you can view the examples:

### Example 1 - Query params

this one uses query parameters

http://localhost:4000/example-1?id=%3C/script%3E%3Cscript%3Ealert('I%20%3C3%20GraphQL.%20Hack%20the%20Planet!!')%3C/script%3E%3Cscript%3E

### Example 2 - DB Example

this one uses a mock database, to demonstrate more ways in which the function is susceptible

http://localhost:4000/example-2

### Example 3 - Upgrade workaround example

this one uses query like number 1, but shows how to use [`xss`](https://npmjs.com/xss) module to workaround the issue if you aren't able to upgrade

http://localhost:4000/example-3?id=%3C/script%3E%3Cscript%3Ealert('I%20%3C3%20GraphQL.%20Hack%20the%20Planet!!')%3C/script%3E%3Cscript%3E

### Example 4 - Always Safe example

this one uses static values, so it's safe without any workarounds! (try removing the ?darkMode parameter)

http://localhost:4000/example-4?darkMode=%3C/script%3E%3Cscript%3Ealert('I%20%3C3%20GraphQL.%20Hack%20the%20Planet!!')%3C/script%3E%3Cscript%3E

[XSS Safe using static configuration strings]("http://localhost:4000/example-3?darkMode")

## More Details

See more details in [SECURITY.md](../../../../SECURITY.md)


================================================
FILE: packages/graphql-playground-html/examples/xss-attack/index.js
================================================
const express = require('express')
const { ApolloServer, gql } = require('apollo-server-express')
const { filterXSS } = require('xss')
const { renderPlaygroundPage } = require('graphql-playground-html')

const typeDefs = gql`
  type Query {
    hello: String!
  }
  schema {
    query: Query
  }
`
const resolvers = {
  Query: {
    hello: () => 'world',
  },
}

const PORT = 4000

const server = new ApolloServer({ typeDefs, resolvers })

const app = express()
server.applyMiddleware({ app })

// Example 1: Query Parameters

app.get('/example-1', (req, res, next) => {
  res.write(
    renderPlaygroundPage({
      endpoint: `/graphql/${req.query.id}`,
    }),
  )
  res.status(200)
  next()
})

// Example 2: mock database example

const db = {
  async get() {
    return {
      'editor.fontFamily': `</script><script>alert('I <3 GraphQL. Hack the Planet!!')</script><script>`,
    }
  },
}

app.get('/example-2', async (req, res, next) => {
  const settings = await db.get()
  res.write(
    renderPlaygroundPage({
      endpoint: '/graphql',
      settings,
    }),
  )
  next()
})

// Example 3: Manual Workaround

const filter = (val) => {
  return filterXSS(val, {
    // @ts-ignore
    whiteList: [],
    stripIgnoreTag: true,
    stripIgnoreTagBody: ['script'],
  })
}

app.get('/example-3', (req, res, next) => {
  res.write(
    renderPlaygroundPage({
      endpoint: `/graphql/${filter(req.query.id)}`,
    }),
  )
  res.status(200)
  next()
})

// Example 4: Safe

app.get('/example-4', (req, res, next) => {
  res.write(
    renderPlaygroundPage({
      endpoint: `/graphql`,
      settings: {
        'editor.theme': req.query.darkMode ? 'dark' : 'light',
      },
    }),
  )
  res.status(200)
  next()
})

app.listen(PORT)

console.log(
  `Serving the GraphQL Playground on http://localhost:${PORT}/example-2`,
)


================================================
FILE: packages/graphql-playground-html/examples/xss-attack/package.json
================================================
{
  "name": "xss-attack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "apollo-server-express": "^2.16.0",
    "express": "^4.17.1",
    "graphql": "^15.0.0",
    "graphql-playground-html": "1.6.20",
    "xss": "^1.0.6"
  }
}


================================================
FILE: packages/graphql-playground-html/minimal.html
================================================
<!DOCTYPE html>
<html>

<head>
  <meta charset=utf-8/>
  <meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
  <title>GraphQL Playground</title>
  <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/css/index.css" />
  <link rel="shortcut icon" href="//cdn.jsdelivr.net/npm/graphql-playground-react/build/favicon.png" />
  <script src="//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/js/middleware.js"></script>
</head>

<body>
  <div id="root">
    <style>
      body {
        background-color: rgb(23, 42, 58);
        font-family: Open Sans, sans-serif;
        height: 90vh;
      }

      #root {
        height: 100%;
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
      }

      .loading {
        font-size: 32px;
        font-weight: 200;
        color: rgba(255, 255, 255, .6);
        margin-left: 20px;
      }

      img {
        width: 78px;
        height: 78px;
      }

      .title {
        font-weight: 400;
      }
    </style>
    <img src='//cdn.jsdelivr.net/npm/graphql-playground-react/build/logo.png' alt=''>
    <div class="loading"> Loading
      <span class="title">GraphQL Playground</span>
    </div>
  </div>
  <script>window.addEventListener('load', function (event) {
      GraphQLPlayground.init(document.getElementById('root'), {
        // options as 'endpoint' belong here
      })
    })</script>
</body>

</html>

================================================
FILE: packages/graphql-playground-html/minimalWithoutCDN.html
================================================
<!DOCTYPE html>
<html>

<head>
  <meta charset=utf-8 />
  <meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
  <title>GraphQL Playground</title>
  <link rel="stylesheet" href="./node_modules/graphql-playground-react/build/static/css/index.css" />
  <link rel="shortcut icon" href="./node_modules/graphql-playground-react/build/favicon.png" />
  <script src="./node_modules/graphql-playground-react/build/static/js/middleware.js"></script>
</head>

<body>
  <div id="root">
    <style>
      body {
        background-color: rgb(23, 42, 58);
        font-family: Open Sans, sans-serif;
        height: 90vh;
      }

      #root {
        height: 100%;
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
      }

      .loading {
        font-size: 32px;
        font-weight: 200;
        color: rgba(255, 255, 255, .6);
        margin-left: 20px;
      }

      img {
        width: 78px;
        height: 78px;
      }

      .title {
        font-weight: 400;
      }
    </style>
    <img src='./node_modules/graphql-playground-react/build/logo.png' alt=''>
    <div class="loading"> Loading
      <span class="title">GraphQL Playground</span>
    </div>
  </div>
  <script>window.addEventListener('load', function (event) {
      GraphQLPlayground.init(document.getElementById('root'), {
        // options as 'endpoint' belong here
      })
    })</script>
</body>

</html>

================================================
FILE: packages/graphql-playground-html/package.json
================================================
{
  "name": "graphql-playground-html",
  "version": "1.6.29",
  "homepage": "https://github.com/graphcool/graphql-playground/tree/main/packages/graphql-playground-html",
  "description": "GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration).",
  "contributors": [
    "Tim Suchanek <tim@graph.cool>",
    "Johannes Schickling <johannes@graph.cool>",
    "Mohammad Rajabifard <mo.rajbi@gmail.com>"
  ],
  "repository": "http://github.com/graphcool/graphql-playground.git",
  "license": "MIT",
  "main": "dist/index.js",
  "files": [
    "dist"
  ],
  "scripts": {
    "build": "rimraf dist && tsc",
    "prepare": "npm run build"
  },
  "keywords": [
    "graphql",
    "graphiql",
    "playground",
    "graphcool"
  ],
  "devDependencies": {
    "@types/node": "12.12.34",
    "rimraf": "3.0.2",
    "typescript": "3.8.3"
  },
  "typings": "dist/index.d.ts",
  "typescript": {
    "definition": "dist/index.d.ts"
  },
  "dependencies": {
    "xss": "^1.0.6"
  },
  "gitHead": "53d233f9deb9dcc86f99e41268ff92b6367e0713"
}


================================================
FILE: packages/graphql-playground-html/src/get-loading-markup.ts
================================================
const getLoadingMarkup = () => ({
  script: `
    const loadingWrapper = document.getElementById('loading-wrapper');
    if (loadingWrapper) {
      loadingWrapper.classList.add('fadeOut');
    }
    `,
  container: `
<style type="text/css">
.fadeOut {
  -webkit-animation: fadeOut 0.5s ease-out forwards;
  animation: fadeOut 0.5s ease-out forwards;
}

@-webkit-keyframes fadeIn {
  from {
    opacity: 0;
    -webkit-transform: translateY(-10px);
    -ms-transform: translateY(-10px);
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    -webkit-transform: translateY(0);
    -ms-transform: translateY(0);
    transform: translateY(0);
  }
}

@keyframes fadeIn {
  from {
    opacity: 0;
    -webkit-transform: translateY(-10px);
    -ms-transform: translateY(-10px);
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    -webkit-transform: translateY(0);
    -ms-transform: translateY(0);
    transform: translateY(0);
  }
}

@-webkit-keyframes fadeOut {
  from {
    opacity: 1;
    -webkit-transform: translateY(0);
    -ms-transform: translateY(0);
    transform: translateY(0);
  }
  to {
    opacity: 0;
    -webkit-transform: translateY(-10px);
    -ms-transform: translateY(-10px);
    transform: translateY(-10px);
  }
}

@keyframes fadeOut {
  from {
    opacity: 1;
    -webkit-transform: translateY(0);
    -ms-transform: translateY(0);
    transform: translateY(0);
  }
  to {
    opacity: 0;
    -webkit-transform: translateY(-10px);
    -ms-transform: translateY(-10px);
    transform: translateY(-10px);
  }
}

@-webkit-keyframes appearIn {
  from {
    opacity: 0;
    -webkit-transform: translateY(0px);
    -ms-transform: translateY(0px);
    transform: translateY(0px);
  }
  to {
    opacity: 1;
    -webkit-transform: translateY(0);
    -ms-transform: translateY(0);
    transform: translateY(0);
  }
}

@keyframes appearIn {
  from {
    opacity: 0;
    -webkit-transform: translateY(0px);
    -ms-transform: translateY(0px);
    transform: translateY(0px);
  }
  to {
    opacity: 1;
    -webkit-transform: translateY(0);
    -ms-transform: translateY(0);
    transform: translateY(0);
  }
}

@-webkit-keyframes scaleIn {
  from {
    -webkit-transform: scale(0);
    -ms-transform: scale(0);
    transform: scale(0);
  }
  to {
    -webkit-transform: scale(1);
    -ms-transform: scale(1);
    transform: scale(1);
  }
}

@keyframes scaleIn {
  from {
    -webkit-transform: scale(0);
    -ms-transform: scale(0);
    transform: scale(0);
  }
  to {
    -webkit-transform: scale(1);
    -ms-transform: scale(1);
    transform: scale(1);
  }
}

@-webkit-keyframes innerDrawIn {
  0% {
    stroke-dashoffset: 70;
  }
  50% {
    stroke-dashoffset: 140;
  }
  100% {
    stroke-dashoffset: 210;
  }
}

@keyframes innerDrawIn {
  0% {
    stroke-dashoffset: 70;
  }
  50% {
    stroke-dashoffset: 140;
  }
  100% {
    stroke-dashoffset: 210;
  }
}

@-webkit-keyframes outerDrawIn {
  0% {
    stroke-dashoffset: 76;
  }
  100% {
    stroke-dashoffset: 152;
  }
}

@keyframes outerDrawIn {
  0% {
    stroke-dashoffset: 76;
  }
  100% {
    stroke-dashoffset: 152;
  }
}

.hHWjkv {
  -webkit-transform-origin: 0px 0px;
  -ms-transform-origin: 0px 0px;
  transform-origin: 0px 0px;
  -webkit-transform: scale(0);
  -ms-transform: scale(0);
  transform: scale(0);
  -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;
  animation: scaleIn 0.25s linear forwards 0.2222222222222222s;
}

.gCDOzd {
  -webkit-transform-origin: 0px 0px;
  -ms-transform-origin: 0px 0px;
  transform-origin: 0px 0px;
  -webkit-transform: scale(0);
  -ms-transform: scale(0);
  transform: scale(0);
  -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;
  animation: scaleIn 0.25s linear forwards 0.4222222222222222s;
}

.hmCcxi {
  -webkit-transform-origin: 0px 0px;
  -ms-transform-origin: 0px 0px;
  transform-origin: 0px 0px;
  -webkit-transform: scale(0);
  -ms-transform: scale(0);
  transform: scale(0);
  -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;
  animation: scaleIn 0.25s linear forwards 0.6222222222222222s;
}

.eHamQi {
  -webkit-transform-origin: 0px 0px;
  -ms-transform-origin: 0px 0px;
  transform-origin: 0px 0px;
  -webkit-transform: scale(0);
  -ms-transform: scale(0);
  transform: scale(0);
  -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;
  animation: scaleIn 0.25s linear forwards 0.8222222222222223s;
}

.byhgGu {
  -webkit-transform-origin: 0px 0px;
  -ms-transform-origin: 0px 0px;
  transform-origin: 0px 0px;
  -webkit-transform: scale(0);
  -ms-transform: scale(0);
  transform: scale(0);
  -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;
  animation: scaleIn 0.25s linear forwards 1.0222222222222221s;
}

.llAKP {
  -webkit-transform-origin: 0px 0px;
  -ms-transform-origin: 0px 0px;
  transform-origin: 0px 0px;
  -webkit-transform: scale(0);
  -ms-transform: scale(0);
  transform: scale(0);
  -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;
  animation: scaleIn 0.25s linear forwards 1.2222222222222223s;
}

.bglIGM {
  -webkit-transform-origin: 64px 28px;
  -ms-transform-origin: 64px 28px;
  transform-origin: 64px 28px;
  -webkit-transform: scale(0);
  -ms-transform: scale(0);
  transform: scale(0);
  -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;
  animation: scaleIn 0.25s linear forwards 0.2222222222222222s;
}

.ksxRII {
  -webkit-transform-origin: 95.98500061035156px 46.510000228881836px;
  -ms-transform-origin: 95.98500061035156px 46.510000228881836px;
  transform-origin: 95.98500061035156px 46.510000228881836px;
  -webkit-transform: scale(0);
  -ms-transform: scale(0);
  transform: scale(0);
  -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;
  animation: scaleIn 0.25s linear forwards 0.4222222222222222s;
}

.cWrBmb {
  -webkit-transform-origin: 95.97162628173828px 83.4900016784668px;
  -ms-transform-origin: 95.97162628173828px 83.4900016784668px;
  transform-origin: 95.97162628173828px 83.4900016784668px;
  -webkit-transform: scale(0);
  -ms-transform: scale(0);
  transform: scale(0);
  -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;
  animation: scaleIn 0.25s linear forwards 0.6222222222222222s;
}

.Wnusb {
  -webkit-transform-origin: 64px 101.97999572753906px;
  -ms-transform-origin: 64px 101.97999572753906px;
  transform-origin: 64px 101.97999572753906px;
  -webkit-transform: scale(0);
  -ms-transform: scale(0);
  transform: scale(0);
  -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;
  animation: scaleIn 0.25s linear forwards 0.8222222222222223s;
}

.bfPqf {
  -webkit-transform-origin: 32.03982162475586px 83.4900016784668px;
  -ms-transform-origin: 32.03982162475586px 83.4900016784668px;
  transform-origin: 32.03982162475586px 83.4900016784668px;
  -webkit-transform: scale(0);
  -ms-transform: scale(0);
  transform: scale(0);
  -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;
  animation: scaleIn 0.25s linear forwards 1.0222222222222221s;
}

.edRCTN {
  -webkit-transform-origin: 32.033552169799805px 46.510000228881836px;
  -ms-transform-origin: 32.033552169799805px 46.510000228881836px;
  transform-origin: 32.033552169799805px 46.510000228881836px;
  -webkit-transform: scale(0);
  -ms-transform: scale(0);
  transform: scale(0);
  -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;
  animation: scaleIn 0.25s linear forwards 1.2222222222222223s;
}

.iEGVWn {
  opacity: 0;
  stroke-dasharray: 76;
  -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;
  animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;
  -webkit-animation-iteration-count: 1, 1;
  animation-iteration-count: 1, 1;
}

.bsocdx {
  opacity: 0;
  stroke-dasharray: 76;
  -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;
  animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;
  -webkit-animation-iteration-count: 1, 1;
  animation-iteration-count: 1, 1;
}

.jAZXmP {
  opacity: 0;
  stroke-dasharray: 76;
  -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;
  animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;
  -webkit-animation-iteration-count: 1, 1;
  animation-iteration-count: 1, 1;
}

.hSeArx {
  opacity: 0;
  stroke-dasharray: 76;
  -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;
  animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;
  -webkit-animation-iteration-count: 1, 1;
  animation-iteration-count: 1, 1;
}

.bVgqGk {
  opacity: 0;
  stroke-dasharray: 76;
  -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;
  animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;
  -webkit-animation-iteration-count: 1, 1;
  animation-iteration-count: 1, 1;
}

.hEFqBt {
  opacity: 0;
  stroke-dasharray: 76;
  -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;
  animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;
  -webkit-animation-iteration-count: 1, 1;
  animation-iteration-count: 1, 1;
}

.dzEKCM {
  opacity: 0;
  stroke-dasharray: 70;
  -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;
  animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;
  -webkit-animation-iteration-count: infinite, 1;
  animation-iteration-count: infinite, 1;
}

.DYnPx {
  opacity: 0;
  stroke-dasharray: 70;
  -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;
  animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;
  -webkit-animation-iteration-count: infinite, 1;
  animation-iteration-count: infinite, 1;
}

.hjPEAQ {
  opacity: 0;
  stroke-dasharray: 70;
  -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;
  animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;
  -webkit-animation-iteration-count: infinite, 1;
  animation-iteration-count: infinite, 1;
}

#loading-wrapper {
  position: absolute;
  width: 100vw;
  height: 100vh;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-align-items: center;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
  -ms-flex-pack: center;
  justify-content: center;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
}

.logo {
  width: 75px;
  height: 75px;
  margin-bottom: 20px;
  opacity: 0;
  -webkit-animation: fadeIn 0.5s ease-out forwards;
  animation: fadeIn 0.5s ease-out forwards;
}

.text {
  font-size: 32px;
  font-weight: 200;
  text-align: center;
  color: rgba(255, 255, 255, 0.6);
  opacity: 0;
  -webkit-animation: fadeIn 0.5s ease-out forwards;
  animation: fadeIn 0.5s ease-out forwards;
}

.dGfHfc {
  font-weight: 400;
}
</style>
<div id="loading-wrapper">
<svg class="logo" viewBox="0 0 128 128" xmlns:xlink="http://www.w3.org/1999/xlink">
  <title>GraphQL Playground Logo</title>
  <defs>
    <linearGradient id="linearGradient-1" x1="4.86%" x2="96.21%" y1="0%" y2="99.66%">
      <stop stop-color="#E00082" stop-opacity=".8" offset="0%"></stop>
      <stop stop-color="#E00082" offset="100%"></stop>
    </linearGradient>
  </defs>
  <g>
    <rect id="Gradient" width="127.96" height="127.96" y="1" fill="url(#linearGradient-1)" rx="4"></rect>
    <path id="Border" fill="#E00082" fill-rule="nonzero" d="M4.7 2.84c-1.58 0-2.86 1.28-2.86 2.85v116.57c0 1.57 1.28 2.84 2.85 2.84h116.57c1.57 0 2.84-1.26 2.84-2.83V5.67c0-1.55-1.26-2.83-2.83-2.83H4.67zM4.7 0h116.58c3.14 0 5.68 2.55 5.68 5.7v116.58c0 3.14-2.54 5.68-5.68 5.68H4.68c-3.13 0-5.68-2.54-5.68-5.68V5.68C-1 2.56 1.55 0 4.7 0z"></path>
    <path class="bglIGM" x="64" y="28" fill="#fff" d="M64 36c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8" style="transform: translate(100px, 100px);"></path>
    <path class="ksxRII" x="95.98500061035156" y="46.510000228881836" fill="#fff" d="M89.04 50.52c-2.2-3.84-.9-8.73 2.94-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.76.9-10.97-2.94"
      style="transform: translate(100px, 100px);"></path>
    <path class="cWrBmb" x="95.97162628173828" y="83.4900016784668" fill="#fff" d="M102.9 87.5c-2.2 3.84-7.1 5.15-10.94 2.94-3.84-2.2-5.14-7.12-2.94-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.86 2.23 5.16 7.12 2.94 10.96"
      style="transform: translate(100px, 100px);"></path>
    <path class="Wnusb" x="64" y="101.97999572753906" fill="#fff" d="M64 110c-4.43 0-8-3.6-8-8.02 0-4.44 3.57-8.02 8-8.02s8 3.58 8 8.02c0 4.4-3.57 8.02-8 8.02"
      style="transform: translate(100px, 100px);"></path>
    <path class="bfPqf" x="32.03982162475586" y="83.4900016784668" fill="#fff" d="M25.1 87.5c-2.2-3.84-.9-8.73 2.93-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.74.9-10.95-2.94"
      style="transform: translate(100px, 100px);"></path>
    <path class="edRCTN" x="32.033552169799805" y="46.510000228881836" fill="#fff" d="M38.96 50.52c-2.2 3.84-7.12 5.15-10.95 2.94-3.82-2.2-5.12-7.12-2.92-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.83 2.23 5.14 7.12 2.94 10.96"
      style="transform: translate(100px, 100px);"></path>
    <path class="iEGVWn" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M63.55 27.5l32.9 19-32.9-19z"></path>
    <path class="bsocdx" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M96 46v38-38z"></path>
    <path class="jAZXmP" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M96.45 84.5l-32.9 19 32.9-19z"></path>
    <path class="hSeArx" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M64.45 103.5l-32.9-19 32.9 19z"></path>
    <path class="bVgqGk" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M32 84V46v38z"></path>
    <path class="hEFqBt" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M31.55 46.5l32.9-19-32.9 19z"></path>
    <path class="dzEKCM" id="Triangle-Bottom" stroke="#fff" stroke-width="4" d="M30 84h70" stroke-linecap="round"></path>
    <path class="DYnPx" id="Triangle-Left" stroke="#fff" stroke-width="4" d="M65 26L30 87" stroke-linecap="round"></path>
    <path class="hjPEAQ" id="Triangle-Right" stroke="#fff" stroke-width="4" d="M98 87L63 26" stroke-linecap="round"></path>
  </g>
</svg>
<div class="text">Loading
  <span class="dGfHfc">GraphQL Playground</span>
</div>
</div>
`,
})

export default getLoadingMarkup


================================================
FILE: packages/graphql-playground-html/src/index.ts
================================================
export {
  renderPlaygroundPage,
  MiddlewareOptions,
  RenderPageOptions,
} from './render-playground-page'


================================================
FILE: packages/graphql-playground-html/src/render-playground-page.ts
================================================
import { filterXSS } from 'xss';

import getLoadingMarkup from './get-loading-markup'

export interface MiddlewareOptions {
  endpoint?: string
  subscriptionEndpoint?: string
  workspaceName?: string
  env?: any
  config?: any
  settings?: Partial<ISettings>
  schema?: IntrospectionResult
  tabs?: Tab[]
  codeTheme?: EditorColours
}

export type CursorShape = 'line' | 'block' | 'underline'
export type Theme = 'dark' | 'light'

export interface ISettings {
  'general.betaUpdates': boolean
  'editor.cursorShape': CursorShape
  'editor.theme': Theme
  'editor.reuseHeaders': boolean
  'tracing.hideTracingResponse': boolean
  'tracing.tracingSupported': boolean
  'editor.fontSize': number
  'editor.fontFamily': string
  'request.credentials': string
  'request.globalHeaders': { [key: string]: string; }
  'schema.polling.enable': boolean
  'schema.polling.endpointFilter': string
  'schema.polling.interval': number
}

export interface EditorColours {
  property: string
  comment: string
  punctuation: string
  keyword: string
  def: string
  qualifier: string
  attribute: string
  number: string
  string: string
  builtin: string
  string2: string
  variable: string
  meta: string
  atom: string
  ws: string
  selection: string
  cursorColor: string
  editorBackground: string
  resultBackground: string
  leftDrawerBackground: string
  rightDrawerBackground: string
}

export interface IntrospectionResult {
  __schema: any
}

export interface RenderPageOptions extends MiddlewareOptions {
  version?: string
  cdnUrl?: string
  env?: any
  title?: string
  faviconUrl?: string | null
}

export interface Tab {
  endpoint: string
  query: string
  name?: string
  variables?: string
  responses?: string[]
  headers?: { [key: string]: string }
}

const filter = (val) => {
  return filterXSS(val, {
    // @ts-ignore
    whiteList: [],
    stripIgnoreTag: true,
    stripIgnoreTagBody: ["script"]
  })
}


const loading = getLoadingMarkup()

const CONFIG_ID = 'playground-config';

const getCdnMarkup = ({ version, cdnUrl = '//cdn.jsdelivr.net/npm', faviconUrl }) => {
  const buildCDNUrl = (packageName: string, suffix: string) => filter(`${cdnUrl}/${packageName}${version ? `@${version}` : ''}/${suffix}` || '')
  return `
    <link 
      rel="stylesheet" 
      href="${buildCDNUrl('graphql-playground-react', 'build/static/css/index.css')}"
    />
    ${typeof faviconUrl === 'string' ? `<link rel="shortcut icon" href="${filter(faviconUrl || '')}" />` : ''}
    ${faviconUrl === undefined ? `<link rel="shortcut icon" href="${buildCDNUrl('graphql-playground-react', 'build/favicon.png')}" />` : ''}
    <script 
      src="${buildCDNUrl('graphql-playground-react', 'build/static/js/middleware.js')}"
    ></script>
`}


const renderConfig = (config) => {
  return filterXSS(`<div id="${CONFIG_ID}">${JSON.stringify(config)}</div>`, {
    whiteList: { div: ['id'] },
  })
}

export function renderPlaygroundPage(options: RenderPageOptions) {
  const extendedOptions: any = {
    ...options,
    canSaveConfig: false,
  }
  // for compatibility
  if ((options as any).subscriptionsEndpoint) {
    extendedOptions.subscriptionEndpoint = filter((options as any).subscriptionsEndpoint || '')
  }
  if (options.config) {
    extendedOptions.configString = JSON.stringify(options.config, null, 2)
  }
  if (!extendedOptions.endpoint && !extendedOptions.configString) {
    /* tslint:disable-next-line */
    console.warn(
      `WARNING: You didn't provide an endpoint and don't have a .graphqlconfig. Make sure you have at least one of them.`,
    )
  }
  else if (extendedOptions.endpoint) {
    extendedOptions.endpoint = filter(extendedOptions.endpoint || '')
  }

  return `
  <!DOCTYPE html>
  <html>
  <head>
    <meta charset=utf-8 />
    <meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
    <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700|Source+Code+Pro:400,700" rel="stylesheet">
    <title>${extendedOptions.title || 'GraphQL Playground'}</title>
    ${extendedOptions.env === 'react' || extendedOptions.env === 'electron'
      ? ''
      : getCdnMarkup(extendedOptions)
    }
  </head>
  <body>
    <style type="text/css">
      html {
        font-family: "Open Sans", sans-serif;
        overflow: hidden;
      }
  
      body {
        margin: 0;
        background: #172a3a;
      }

      #${CONFIG_ID} {
        display: none;
      }
  
      .playgroundIn {
        -webkit-animation: playgroundIn 0.5s ease-out forwards;
        animation: playgroundIn 0.5s ease-out forwards;
      }
  
      @-webkit-keyframes playgroundIn {
        from {
          opacity: 0;
          -webkit-transform: translateY(10px);
          -ms-transform: translateY(10px);
          transform: translateY(10px);
        }
        to {
          opacity: 1;
          -webkit-transform: translateY(0);
          -ms-transform: translateY(0);
          transform: translateY(0);
        }
      }
  
      @keyframes playgroundIn {
        from {
          opacity: 0;
          -webkit-transform: translateY(10px);
          -ms-transform: translateY(10px);
          transform: translateY(10px);
        }
        to {
          opacity: 1;
          -webkit-transform: translateY(0);
          -ms-transform: translateY(0);
          transform: translateY(0);
        }
      }
    </style>
    ${loading.container}
    ${renderConfig(extendedOptions)}
    <div id="root" />
    <script type="text/javascript">
      window.addEventListener('load', function (event) {
        ${loading.script}
  
        const root = document.getElementById('root');
        root.classList.add('playgroundIn');
        const configText = document.getElementById('${CONFIG_ID}').innerText;
        
        if(configText && configText.length) {
          try {
            GraphQLPlayground.init(root, JSON.parse(configText));
          }
          catch(err) {
            console.error("could not find config")
          }
        }
        else {
          GraphQLPlayground.init(root);
        }
      })
    </script>
  </body>
  </html>
`
}


================================================
FILE: packages/graphql-playground-html/tsconfig.json
================================================
{
  "compilerOptions": {
    "outDir": "dist",
    "target": "es5",
    "lib": ["esnext", "dom"],
    "sourceMap": true,
    "rootDir": "src",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": false,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "declaration": true
  }
}


================================================
FILE: packages/graphql-playground-html/withAnimation.html
================================================
<!DOCTYPE html>

<html>

<head>
  <meta charset=utf-8 />
  <meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
  <title>GraphQL Playground</title>
  <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/css/index.css" />
  <link rel="shortcut icon" href="//cdn.jsdelivr.net/npm/graphql-playground-react/build/favicon.png" />
  <script src="//cdn.jsdelivr.net/npm/graphql-playground-react/build/static/js/middleware.js"></script>

</head>

<body>
  <style type="text/css">
    html {
      font-family: "Open Sans", sans-serif;
      overflow: hidden;
    }

    body {
      margin: 0;
      background: #172a3a;
    }

    .playgroundIn {
      -webkit-animation: playgroundIn 0.5s ease-out forwards;
      animation: playgroundIn 0.5s ease-out forwards;
    }

    @-webkit-keyframes playgroundIn {
      from {
        opacity: 0;
        -webkit-transform: translateY(10px);
        -ms-transform: translateY(10px);
        transform: translateY(10px);
      }
      to {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
    }

    @keyframes playgroundIn {
      from {
        opacity: 0;
        -webkit-transform: translateY(10px);
        -ms-transform: translateY(10px);
        transform: translateY(10px);
      }
      to {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
    }
  </style>

  <style type="text/css">
    .fadeOut {
      -webkit-animation: fadeOut 0.5s ease-out forwards;
      animation: fadeOut 0.5s ease-out forwards;
    }

    @-webkit-keyframes fadeIn {
      from {
        opacity: 0;
        -webkit-transform: translateY(-10px);
        -ms-transform: translateY(-10px);
        transform: translateY(-10px);
      }
      to {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
    }

    @keyframes fadeIn {
      from {
        opacity: 0;
        -webkit-transform: translateY(-10px);
        -ms-transform: translateY(-10px);
        transform: translateY(-10px);
      }
      to {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
    }

    @-webkit-keyframes fadeOut {
      from {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
      to {
        opacity: 0;
        -webkit-transform: translateY(-10px);
        -ms-transform: translateY(-10px);
        transform: translateY(-10px);
      }
    }

    @keyframes fadeOut {
      from {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
      to {
        opacity: 0;
        -webkit-transform: translateY(-10px);
        -ms-transform: translateY(-10px);
        transform: translateY(-10px);
      }
    }

    @-webkit-keyframes appearIn {
      from {
        opacity: 0;
        -webkit-transform: translateY(0px);
        -ms-transform: translateY(0px);
        transform: translateY(0px);
      }
      to {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
    }

    @keyframes appearIn {
      from {
        opacity: 0;
        -webkit-transform: translateY(0px);
        -ms-transform: translateY(0px);
        transform: translateY(0px);
      }
      to {
        opacity: 1;
        -webkit-transform: translateY(0);
        -ms-transform: translateY(0);
        transform: translateY(0);
      }
    }

    @-webkit-keyframes scaleIn {
      from {
        -webkit-transform: scale(0);
        -ms-transform: scale(0);
        transform: scale(0);
      }
      to {
        -webkit-transform: scale(1);
        -ms-transform: scale(1);
        transform: scale(1);
      }
    }

    @keyframes scaleIn {
      from {
        -webkit-transform: scale(0);
        -ms-transform: scale(0);
        transform: scale(0);
      }
      to {
        -webkit-transform: scale(1);
        -ms-transform: scale(1);
        transform: scale(1);
      }
    }

    @-webkit-keyframes innerDrawIn {
      0% {
        stroke-dashoffset: 70;
      }
      50% {
        stroke-dashoffset: 140;
      }
      100% {
        stroke-dashoffset: 210;
      }
    }

    @keyframes innerDrawIn {
      0% {
        stroke-dashoffset: 70;
      }
      50% {
        stroke-dashoffset: 140;
      }
      100% {
        stroke-dashoffset: 210;
      }
    }

    @-webkit-keyframes outerDrawIn {
      0% {
        stroke-dashoffset: 76;
      }
      100% {
        stroke-dashoffset: 152;
      }
    }

    @keyframes outerDrawIn {
      0% {
        stroke-dashoffset: 76;
      }
      100% {
        stroke-dashoffset: 152;
      }
    }

    .hHWjkv {
      -webkit-transform-origin: 0px 0px;
      -ms-transform-origin: 0px 0px;
      transform-origin: 0px 0px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;
      animation: scaleIn 0.25s linear forwards 0.2222222222222222s;
    }

    .gCDOzd {
      -webkit-transform-origin: 0px 0px;
      -ms-transform-origin: 0px 0px;
      transform-origin: 0px 0px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;
      animation: scaleIn 0.25s linear forwards 0.4222222222222222s;
    }

    .hmCcxi {
      -webkit-transform-origin: 0px 0px;
      -ms-transform-origin: 0px 0px;
      transform-origin: 0px 0px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;
      animation: scaleIn 0.25s linear forwards 0.6222222222222222s;
    }

    .eHamQi {
      -webkit-transform-origin: 0px 0px;
      -ms-transform-origin: 0px 0px;
      transform-origin: 0px 0px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;
      animation: scaleIn 0.25s linear forwards 0.8222222222222223s;
    }

    .byhgGu {
      -webkit-transform-origin: 0px 0px;
      -ms-transform-origin: 0px 0px;
      transform-origin: 0px 0px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;
      animation: scaleIn 0.25s linear forwards 1.0222222222222221s;
    }

    .llAKP {
      -webkit-transform-origin: 0px 0px;
      -ms-transform-origin: 0px 0px;
      transform-origin: 0px 0px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;
      animation: scaleIn 0.25s linear forwards 1.2222222222222223s;
    }

    .bglIGM {
      -webkit-transform-origin: 64px 28px;
      -ms-transform-origin: 64px 28px;
      transform-origin: 64px 28px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.2222222222222222s;
      animation: scaleIn 0.25s linear forwards 0.2222222222222222s;
    }

    .ksxRII {
      -webkit-transform-origin: 95.98500061035156px 46.510000228881836px;
      -ms-transform-origin: 95.98500061035156px 46.510000228881836px;
      transform-origin: 95.98500061035156px 46.510000228881836px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.4222222222222222s;
      animation: scaleIn 0.25s linear forwards 0.4222222222222222s;
    }

    .cWrBmb {
      -webkit-transform-origin: 95.97162628173828px 83.4900016784668px;
      -ms-transform-origin: 95.97162628173828px 83.4900016784668px;
      transform-origin: 95.97162628173828px 83.4900016784668px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.6222222222222222s;
      animation: scaleIn 0.25s linear forwards 0.6222222222222222s;
    }

    .Wnusb {
      -webkit-transform-origin: 64px 101.97999572753906px;
      -ms-transform-origin: 64px 101.97999572753906px;
      transform-origin: 64px 101.97999572753906px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 0.8222222222222223s;
      animation: scaleIn 0.25s linear forwards 0.8222222222222223s;
    }

    .bfPqf {
      -webkit-transform-origin: 32.03982162475586px 83.4900016784668px;
      -ms-transform-origin: 32.03982162475586px 83.4900016784668px;
      transform-origin: 32.03982162475586px 83.4900016784668px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 1.0222222222222221s;
      animation: scaleIn 0.25s linear forwards 1.0222222222222221s;
    }

    .edRCTN {
      -webkit-transform-origin: 32.033552169799805px 46.510000228881836px;
      -ms-transform-origin: 32.033552169799805px 46.510000228881836px;
      transform-origin: 32.033552169799805px 46.510000228881836px;
      -webkit-transform: scale(0);
      -ms-transform: scale(0);
      transform: scale(0);
      -webkit-animation: scaleIn 0.25s linear forwards 1.2222222222222223s;
      animation: scaleIn 0.25s linear forwards 1.2222222222222223s;
    }

    .iEGVWn {
      opacity: 0;
      stroke-dasharray: 76;
      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;
      animation: outerDrawIn 0.5s ease-out forwards 0.3333333333333333s, appearIn 0.1s ease-out forwards 0.3333333333333333s;
      -webkit-animation-iteration-count: 1, 1;
      animation-iteration-count: 1, 1;
    }

    .bsocdx {
      opacity: 0;
      stroke-dasharray: 76;
      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;
      animation: outerDrawIn 0.5s ease-out forwards 0.5333333333333333s, appearIn 0.1s ease-out forwards 0.5333333333333333s;
      -webkit-animation-iteration-count: 1, 1;
      animation-iteration-count: 1, 1;
    }

    .jAZXmP {
      opacity: 0;
      stroke-dasharray: 76;
      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;
      animation: outerDrawIn 0.5s ease-out forwards 0.7333333333333334s, appearIn 0.1s ease-out forwards 0.7333333333333334s;
      -webkit-animation-iteration-count: 1, 1;
      animation-iteration-count: 1, 1;
    }

    .hSeArx {
      opacity: 0;
      stroke-dasharray: 76;
      -webkit-animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;
      animation: outerDrawIn 0.5s ease-out forwards 0.9333333333333333s, appearIn 0.1s ease-out forwards 0.9333333333333333s;
      -webkit-animation-iteration-count: 1, 1;
      animation-iteration-count: 1, 1;
    }

    .bVgqGk {
      opacity: 0;
      stroke-dasharray: 76;
      -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;
      animation: outerDrawIn 0.5s ease-out forwards 1.1333333333333333s, appearIn 0.1s ease-out forwards 1.1333333333333333s;
      -webkit-animation-iteration-count: 1, 1;
      animation-iteration-count: 1, 1;
    }

    .hEFqBt {
      opacity: 0;
      stroke-dasharray: 76;
      -webkit-animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;
      animation: outerDrawIn 0.5s ease-out forwards 1.3333333333333333s, appearIn 0.1s ease-out forwards 1.3333333333333333s;
      -webkit-animation-iteration-count: 1, 1;
      animation-iteration-count: 1, 1;
    }

    .dzEKCM {
      opacity: 0;
      stroke-dasharray: 70;
      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;
      animation: innerDrawIn 1s ease-in-out forwards 1.3666666666666667s, appearIn 0.1s linear forwards 1.3666666666666667s;
      -webkit-animation-iteration-count: infinite, 1;
      animation-iteration-count: infinite, 1;
    }

    .DYnPx {
      opacity: 0;
      stroke-dasharray: 70;
      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;
      animation: innerDrawIn 1s ease-in-out forwards 1.5333333333333332s, appearIn 0.1s linear forwards 1.5333333333333332s;
      -webkit-animation-iteration-count: infinite, 1;
      animation-iteration-count: infinite, 1;
    }

    .hjPEAQ {
      opacity: 0;
      stroke-dasharray: 70;
      -webkit-animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;
      animation: innerDrawIn 1s ease-in-out forwards 1.7000000000000002s, appearIn 0.1s linear forwards 1.7000000000000002s;
      -webkit-animation-iteration-count: infinite, 1;
      animation-iteration-count: infinite, 1;
    }

    #loading-wrapper {
      position: absolute;
      width: 100vw;
      height: 100vh;
      display: -webkit-box;
      display: -webkit-flex;
      display: -ms-flexbox;
      display: flex;
      -webkit-align-items: center;
      -webkit-box-align: center;
      -ms-flex-align: center;
      align-items: center;
      -webkit-box-pack: center;
      -webkit-justify-content: center;
      -ms-flex-pack: center;
      justify-content: center;
      -webkit-flex-direction: column;
      -ms-flex-direction: column;
      flex-direction: column;
    }

    .logo {
      width: 75px;
      height: 75px;
      margin-bottom: 20px;
      opacity: 0;
      -webkit-animation: fadeIn 0.5s ease-out forwards;
      animation: fadeIn 0.5s ease-out forwards;
    }

    .text {
      font-size: 32px;
      font-weight: 200;
      text-align: center;
      color: rgba(255, 255, 255, 0.6);
      opacity: 0;
      -webkit-animation: fadeIn 0.5s ease-out forwards;
      animation: fadeIn 0.5s ease-out forwards;
    }

    .dGfHfc {
      font-weight: 400;
    }
  </style>
  <div id="loading-wrapper">
    <svg class="logo" viewBox="0 0 128 128" xmlns:xlink="http://www.w3.org/1999/xlink">
      <title>GraphQL Playground Logo</title>
      <defs>
        <linearGradient id="linearGradient-1" x1="4.86%" x2="96.21%" y1="0%" y2="99.66%">
          <stop stop-color="#E00082" stop-opacity=".8" offset="0%"></stop>
          <stop stop-color="#E00082" offset="100%"></stop>
        </linearGradient>
      </defs>
      <g>
        <rect id="Gradient" width="127.96" height="127.96" y="1" fill="url(#linearGradient-1)" rx="4"></rect>
        <path id="Border" fill="#E00082" fill-rule="nonzero" d="M4.7 2.84c-1.58 0-2.86 1.28-2.86 2.85v116.57c0 1.57 1.28 2.84 2.85 2.84h116.57c1.57 0 2.84-1.26 2.84-2.83V5.67c0-1.55-1.26-2.83-2.83-2.83H4.67zM4.7 0h116.58c3.14 0 5.68 2.55 5.68 5.7v116.58c0 3.14-2.54 5.68-5.68 5.68H4.68c-3.13 0-5.68-2.54-5.68-5.68V5.68C-1 2.56 1.55 0 4.7 0z"></path>
        <path class="bglIGM" x="64" y="28" fill="#fff" d="M64 36c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8" style="transform: translate(100px, 100px);"></path>
        <path class="ksxRII" x="95.98500061035156" y="46.510000228881836" fill="#fff" d="M89.04 50.52c-2.2-3.84-.9-8.73 2.94-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.76.9-10.97-2.94"
          style="transform: translate(100px, 100px);"></path>
        <path class="cWrBmb" x="95.97162628173828" y="83.4900016784668" fill="#fff" d="M102.9 87.5c-2.2 3.84-7.1 5.15-10.94 2.94-3.84-2.2-5.14-7.12-2.94-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.86 2.23 5.16 7.12 2.94 10.96"
          style="transform: translate(100px, 100px);"></path>
        <path class="Wnusb" x="64" y="101.97999572753906" fill="#fff" d="M64 110c-4.43 0-8-3.6-8-8.02 0-4.44 3.57-8.02 8-8.02s8 3.58 8 8.02c0 4.4-3.57 8.02-8 8.02"
          style="transform: translate(100px, 100px);"></path>
        <path class="bfPqf" x="32.03982162475586" y="83.4900016784668" fill="#fff" d="M25.1 87.5c-2.2-3.84-.9-8.73 2.93-10.96 3.83-2.2 8.72-.9 10.95 2.94 2.2 3.84.9 8.73-2.94 10.96-3.85 2.2-8.74.9-10.95-2.94"
          style="transform: translate(100px, 100px);"></path>
        <path class="edRCTN" x="32.033552169799805" y="46.510000228881836" fill="#fff" d="M38.96 50.52c-2.2 3.84-7.12 5.15-10.95 2.94-3.82-2.2-5.12-7.12-2.92-10.96 2.2-3.84 7.12-5.15 10.95-2.94 3.83 2.23 5.14 7.12 2.94 10.96"
          style="transform: translate(100px, 100px);"></path>
        <path class="iEGVWn" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M63.55 27.5l32.9 19-32.9-19z"></path>
        <path class="bsocdx" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M96 46v38-38z"></path>
        <path class="jAZXmP" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M96.45 84.5l-32.9 19 32.9-19z"></path>
        <path class="hSeArx" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M64.45 103.5l-32.9-19 32.9 19z"></path>
        <path class="bVgqGk" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M32 84V46v38z"></path>
        <path class="hEFqBt" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" d="M31.55 46.5l32.9-19-32.9 19z"></path>
        <path class="dzEKCM" id="Triangle-Bottom" stroke="#fff" stroke-width="4" d="M30 84h70" stroke-linecap="round"></path>
        <path class="DYnPx" id="Triangle-Left" stroke="#fff" stroke-width="4" d="M65 26L30 87" stroke-linecap="round"></path>
        <path class="hjPEAQ" id="Triangle-Right" stroke="#fff" stroke-width="4" d="M98 87L63 26" stroke-linecap="round"></path>
      </g>
    </svg>
    <div class="text">Loading
      <span class="dGfHfc">GraphQL Playground</span>
    </div>
  </div>

  <div id="root" />
  <script type="text/javascript">
    window.addEventListener('load', function (event) {

      const loadingWrapper = document.getElementById('loading-wrapper');
      loadingWrapper.classList.add('fadeOut');


      const root = document.getElementById('root');
      root.classList.add('playgroundIn');

      GraphQLPlayground.init(root, {
        // you can add more options here
      })
    })
  </script>
</body>
</html>


================================================
FILE: packages/graphql-playground-middleware-express/.gitignore
================================================
# See http://help.github.com/ignore-files/ for more about ignoring files.

# dependencies
node_modules
example/node_modules
example/yarn.lock

# testing
/coverage

# production
/dist

# misc
.DS_Store
.env
npm-debug.log
.idea


================================================
FILE: packages/graphql-playground-middleware-express/CHANGELOG.md
================================================
# Change Log

All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [1.7.22](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-express@1.7.21...graphql-playground-middleware-express@1.7.22) (2020-10-20)

**Note:** Version bump only for package graphql-playground-middleware-express





## [1.7.21](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-express@1.7.20...graphql-playground-middleware-express@1.7.21) (2020-09-15)

**Note:** Version bump only for package graphql-playground-middleware-express





## [1.7.20](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-express@1.7.19...graphql-playground-middleware-express@1.7.20) (2020-08-30)

**Note:** Version bump only for package graphql-playground-middleware-express





## [1.7.19](https://github.com/graphcool/graphql-playground/compare/graphql-playground-middleware-express@1.7.15...graphql-playground-middleware-express@1.7.19) (2020-08-30)

**Note:** Version bump only for package graphql-playground-middleware-express





## 1.7.15 (2020-06-07)


### Bug Fixes

* hide config element 😆 ([#1224](https://github.com/graphcool/graphql-playground/issues/1224)) ([a7bdcaa](https://github.com/graphcool/graphql-playground/commit/a7bdcaa669f21603ded80bb9c59c4ab41597161a))
* rectify all versions and references ([#1223](https://github.com/graphcool/graphql-playground/issues/1223)) ([239289b](https://github.com/graphcool/graphql-playground/commit/239289b3e9da1744b23b7ef2694b1ed6370e3c16))
* **deps:** update deps and toolchain, move back to using yarn… ([#1191](https://github.com/graphcool/graphql-playground/issues/1191)) ([824c7a5](https://github.com/graphcool/graphql-playground/commit/824c7a57f0284f022726a8b8840aafc3e8720ccd))
* **deps:** Update express mw to latest graphql
Download .txt
gitextract_3l4bavka/

├── .dependabot/
│   └── config.yml
├── .github/
│   ├── CONTRIBUTING.md
│   ├── ISSUE_TEMPLATE.md
│   └── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .nvmrc
├── .vscode/
│   └── settings.json
├── CODE_OF_CONDUCT.md
├── LICENSE
├── README.md
├── SECURITY.md
├── docs/
│   └── security/
│       ├── 2020-xss-template-injection.md
│       └── 2021-schema-xss-phishing-attack.md
├── lerna.json
├── package.json
├── packages/
│   ├── graphql-playground-electron/
│   │   ├── .babelrc
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── package.json
│   │   ├── postcss.config.js
│   │   ├── src/
│   │   │   ├── main/
│   │   │   │   ├── createWindow.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── menu.ts
│   │   │   │   ├── notify.ts
│   │   │   │   ├── types.ts
│   │   │   │   └── updates.ts
│   │   │   ├── renderer/
│   │   │   │   ├── components/
│   │   │   │   │   ├── App.tsx
│   │   │   │   │   ├── InitialView/
│   │   │   │   │   │   ├── InitialView.tsx
│   │   │   │   │   │   ├── Toggle.tsx
│   │   │   │   │   │   └── data.ts
│   │   │   │   │   ├── Loading.tsx
│   │   │   │   │   └── Root.tsx
│   │   │   │   ├── index.css
│   │   │   │   ├── index.html
│   │   │   │   ├── index.tsx
│   │   │   │   ├── redux/
│   │   │   │   │   ├── actions/
│   │   │   │   │   │   └── history.ts
│   │   │   │   │   ├── createStore.ts
│   │   │   │   │   └── reducers/
│   │   │   │   │       ├── history.ts
│   │   │   │   │       └── index.ts
│   │   │   │   └── utils/
│   │   │   │       └── errify.ts
│   │   │   └── shared/
│   │   │       └── utils.ts
│   │   ├── static/
│   │   │   └── icons/
│   │   │       └── icon.icns
│   │   ├── tsconfig.json
│   │   ├── tslint.json
│   │   ├── typings/
│   │   │   ├── custom.d.ts
│   │   │   └── styled-jsx.d.ts
│   │   ├── webpack.config.build.js
│   │   └── webpack.config.js
│   ├── graphql-playground-html/
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── examples/
│   │   │   └── xss-attack/
│   │   │       ├── README.md
│   │   │       ├── index.js
│   │   │       └── package.json
│   │   ├── minimal.html
│   │   ├── minimalWithoutCDN.html
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── get-loading-markup.ts
│   │   │   ├── index.ts
│   │   │   └── render-playground-page.ts
│   │   ├── tsconfig.json
│   │   └── withAnimation.html
│   ├── graphql-playground-middleware-express/
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── examples/
│   │   │   ├── basic/
│   │   │   │   ├── .envrc
│   │   │   │   ├── .graphqlconfig.yml
│   │   │   │   ├── README.md
│   │   │   │   ├── index.js
│   │   │   │   └── package.json
│   │   │   └── graphcool/
│   │   │       ├── .envrc
│   │   │       ├── .graphqlconfig.yml
│   │   │       ├── README.md
│   │   │       ├── datamodel.graphql
│   │   │       ├── graphcool.yml
│   │   │       ├── index.js
│   │   │       ├── package.json
│   │   │       ├── prisma.yml
│   │   │       └── schema.graphql
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── graphql-playground-middleware-hapi/
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── examples/
│   │   │   └── basic/
│   │   │       ├── README.md
│   │   │       ├── index.js
│   │   │       └── package.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── graphql-playground-middleware-koa/
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── README.md
│   │   ├── examples/
│   │   │   └── basic/
│   │   │       ├── .graphqlconfig.yml
│   │   │       ├── README.md
│   │   │       ├── index.js
│   │   │       └── package.json
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   ├── graphql-playground-middleware-lambda/
│   │   ├── .gitignore
│   │   ├── CHANGELOG.md
│   │   ├── LICENSE
│   │   ├── README.md
│   │   ├── examples/
│   │   │   └── basic/
│   │   │       ├── .gitignore
│   │   │       ├── README.md
│   │   │       ├── handler.js
│   │   │       ├── package.json
│   │   │       └── serverless.yml
│   │   ├── package.json
│   │   ├── src/
│   │   │   └── index.ts
│   │   └── tsconfig.json
│   └── graphql-playground-react/
│       ├── .babelrc
│       ├── .gitignore
│       ├── CHANGELOG.md
│       ├── LICENSE
│       ├── README.md
│       ├── config/
│       │   ├── env.js
│       │   ├── jest/
│       │   │   ├── cssTransform.js
│       │   │   ├── fileTransform.js
│       │   │   └── typescriptTransform.js
│       │   ├── paths.js
│       │   ├── polyfills.js
│       │   ├── webpack.config.dev.js
│       │   ├── webpack.config.prod.js
│       │   └── webpackDevServer.config.js
│       ├── jest.config.js
│       ├── package.json
│       ├── public/
│       │   ├── _headers
│       │   ├── _redirects
│       │   ├── affiliates.graphql
│       │   ├── auth.graphql
│       │   ├── blogging.graphql
│       │   ├── chat.graphql
│       │   ├── conferences.graphql
│       │   ├── empty.graphql
│       │   ├── freecom.graphql
│       │   ├── hn-relay-full.graphql
│       │   ├── hn-relay.graphql
│       │   ├── hn-starter.graphql
│       │   ├── hn.graphql
│       │   ├── index.html
│       │   ├── insta-auth0.graphql
│       │   ├── insta-email.graphql
│       │   ├── insta-expo-auth.graphql
│       │   ├── insta-files.graphql
│       │   ├── instagram-full.graphql
│       │   ├── instagram.graphql
│       │   ├── movies-import.graphql
│       │   ├── pokedex.graphql
│       │   ├── simple-pokedex.graphql
│       │   ├── todo.graphql
│       │   ├── twitter.graphql
│       │   ├── welcome-rp.graphql
│       │   ├── welcome.graphql
│       │   └── worldchat.graphql
│       ├── release.sh
│       ├── scripts/
│       │   ├── build.js
│       │   ├── start.js
│       │   └── test.js
│       ├── src/
│       │   ├── __snapshots__/
│       │   │   └── index.test.tsx.snap
│       │   ├── components/
│       │   │   ├── Button.tsx
│       │   │   ├── Copy.tsx
│       │   │   ├── EndpointPopup.tsx
│       │   │   ├── FileEditor.tsx
│       │   │   ├── GraphQLBinApp.tsx
│       │   │   ├── HistoryPopup/
│       │   │   │   ├── HistoryChooser.tsx
│       │   │   │   ├── HistoryHeader.tsx
│       │   │   │   └── HistoryItems.tsx
│       │   │   ├── HistoryPopup.tsx
│       │   │   ├── Icons/
│       │   │   │   └── index.tsx
│       │   │   ├── MiddlewareApp.tsx
│       │   │   ├── Modal.tsx
│       │   │   ├── Playground/
│       │   │   │   ├── ConfigEditor.tsx
│       │   │   │   ├── DocExplorer/
│       │   │   │   │   ├── Argument.tsx
│       │   │   │   │   ├── ArgumentInline.tsx
│       │   │   │   │   ├── ColumnDoc.tsx
│       │   │   │   │   ├── DocTypeSchema.tsx
│       │   │   │   │   ├── DocsStyles.tsx
│       │   │   │   │   ├── DocsTypes/
│       │   │   │   │   │   ├── DocType.tsx
│       │   │   │   │   │   ├── EnumTypeSchema.tsx
│       │   │   │   │   │   ├── ScalarType.tsx
│       │   │   │   │   │   └── UnionTypeSchema.tsx
│       │   │   │   │   ├── ErrorContainer.tsx
│       │   │   │   │   ├── FieldDoc.tsx
│       │   │   │   │   ├── GraphDocs.tsx
│       │   │   │   │   ├── GraphDocsRoot.tsx
│       │   │   │   │   ├── RootColumn.tsx
│       │   │   │   │   ├── SchemaDoc.tsx
│       │   │   │   │   ├── SearchBox.tsx
│       │   │   │   │   ├── SearchResults.tsx
│       │   │   │   │   └── TypeLink.tsx
│       │   │   │   ├── EditorWrapper.tsx
│       │   │   │   ├── ExecuteButton.tsx
│       │   │   │   ├── ExecuteButtonOperation.tsx
│       │   │   │   ├── ExplorerTabs/
│       │   │   │   │   ├── SideTab.tsx
│       │   │   │   │   └── SideTabs.tsx
│       │   │   │   ├── GraphQLEditor.tsx
│       │   │   │   ├── QueryEditor.tsx
│       │   │   │   ├── ResponseTracing.tsx
│       │   │   │   ├── ResultViewer.tsx
│       │   │   │   ├── Results.tsx
│       │   │   │   ├── SchemaExplorer/
│       │   │   │   │   ├── SDLEditor.tsx
│       │   │   │   │   ├── SDLHeader.tsx
│       │   │   │   │   ├── SDLTypes/
│       │   │   │   │   │   ├── SDLDocType.tsx
│       │   │   │   │   │   ├── SDLFieldDoc.tsx
│       │   │   │   │   │   ├── SDLStyles.tsx
│       │   │   │   │   │   ├── SDLType.tsx
│       │   │   │   │   │   └── SDLUnionType.tsx
│       │   │   │   │   └── SDLView.tsx
│       │   │   │   ├── SchemaFetcher.ts
│       │   │   │   ├── Tab.tsx
│       │   │   │   ├── TabBar.tsx
│       │   │   │   ├── TopBar/
│       │   │   │   │   ├── Polling.tsx
│       │   │   │   │   ├── PollingIcon.tsx
│       │   │   │   │   ├── Positioner.tsx
│       │   │   │   │   ├── Reload.tsx
│       │   │   │   │   ├── ReloadIcon.tsx
│       │   │   │   │   ├── SchemaReload.tsx
│       │   │   │   │   └── TopBar.tsx
│       │   │   │   ├── TracingRow.tsx
│       │   │   │   ├── VariableEditor.tsx
│       │   │   │   ├── onHasCompletion.tsx
│       │   │   │   └── util/
│       │   │   │       ├── InvalidSchemaError.ts
│       │   │   │       ├── NoSchemaError.ts
│       │   │   │       ├── ageOfDate.ts
│       │   │   │       ├── createSDL.ts
│       │   │   │       ├── fibonacci-backoff.ts
│       │   │   │       ├── getQueryFacts.ts
│       │   │   │       ├── getQueryTypes.ts
│       │   │   │       ├── getSelectedOperationName.ts
│       │   │   │       ├── getWorkspaceId.ts
│       │   │   │       ├── hasSubscription.ts
│       │   │   │       ├── immutableMemoize.ts
│       │   │   │       ├── makeOperation.ts
│       │   │   │       ├── parseHeaders.ts
│       │   │   │       ├── session.ts
│       │   │   │       ├── shallowEqual.ts
│       │   │   │       ├── shouldUpdate.ts
│       │   │   │       ├── stack.ts
│       │   │   │       ├── toJS.tsx
│       │   │   │       └── whatChanged.ts
│       │   │   ├── Playground.tsx
│       │   │   ├── PlaygroundWrapper.tsx
│       │   │   ├── Popup.tsx
│       │   │   ├── ProjectsSideNav.tsx
│       │   │   ├── ProjectsSideNavItem.tsx
│       │   │   ├── Root.tsx
│       │   │   ├── Settings.tsx
│       │   │   ├── SettingsEditor.tsx
│       │   │   ├── Share.tsx
│       │   │   ├── Spinner.tsx
│       │   │   ├── Toggle.tsx
│       │   │   ├── ToggleButton.tsx
│       │   │   ├── Tooltip.tsx
│       │   │   ├── asyncComponent.tsx
│       │   │   ├── resolveRefStrings.ts
│       │   │   └── util.ts
│       │   ├── constants.ts
│       │   ├── fixtures/
│       │   │   ├── exampleSchema.ts
│       │   │   └── sdl.ts
│       │   ├── graphqlConfig.ts
│       │   ├── index.css
│       │   ├── index.test.tsx
│       │   ├── index.tsx
│       │   ├── lib.tsx
│       │   ├── localDevIndex.tsx
│       │   ├── middlewareIndex.tsx
│       │   ├── setupEnzyme.ts
│       │   ├── state/
│       │   │   ├── appHistory/
│       │   │   │   ├── actions.ts
│       │   │   │   └── reducers.ts
│       │   │   ├── createStore.ts
│       │   │   ├── docs/
│       │   │   │   ├── actions.ts
│       │   │   │   ├── reducers.ts
│       │   │   │   └── selectors.ts
│       │   │   ├── general/
│       │   │   │   ├── actions.ts
│       │   │   │   ├── reducers.ts
│       │   │   │   └── selectors.ts
│       │   │   ├── history/
│       │   │   │   ├── actions.ts
│       │   │   │   ├── reducers.ts
│       │   │   │   └── selectors.ts
│       │   │   ├── localStorage.ts
│       │   │   ├── rootSaga.ts
│       │   │   ├── sessions/
│       │   │   │   ├── WebSocketLink.ts
│       │   │   │   ├── actions.ts
│       │   │   │   ├── fetchingSagas.ts
│       │   │   │   ├── reducers.ts
│       │   │   │   ├── sagas.ts
│       │   │   │   └── selectors.ts
│       │   │   ├── sharing/
│       │   │   │   ├── actions.ts
│       │   │   │   ├── reducers.ts
│       │   │   │   ├── selectors.ts
│       │   │   │   └── sharingSaga.ts
│       │   │   └── workspace/
│       │   │       ├── actions.ts
│       │   │       ├── deserialize.ts
│       │   │       └── reducers.ts
│       │   ├── styled/
│       │   │   ├── index.ts
│       │   │   ├── styled.ts
│       │   │   └── theme.ts
│       │   ├── types.ts
│       │   ├── utils/
│       │   │   └── performance.ts
│       │   └── utils.ts
│       ├── tests/
│       │   └── schema.faker.graphql
│       ├── tsconfig.build.json
│       ├── tsconfig.jest.json
│       ├── tsconfig.json
│       ├── tslint.json
│       └── typings/
│           ├── custom.d.ts
│           └── styled-jsx.d.ts
├── renovate.json
└── scripts/
    ├── build.sh
    ├── release-html.sh
    ├── release-react.sh
    └── versions.sh
Download .txt
SYMBOL INDEX (609 symbols across 150 files)

FILE: packages/graphql-playground-electron/src/main/createWindow.ts
  function createWindow (line 8) | function createWindow(windowContext: WindowContext) {

FILE: packages/graphql-playground-electron/src/main/index.ts
  function forceSend (line 148) | async function forceSend(channel: string, arg: string, byPath?: string) {

FILE: packages/graphql-playground-electron/src/main/menu.ts
  function send (line 172) | function send(channel: string, arg: string) {

FILE: packages/graphql-playground-electron/src/main/notify.ts
  type NotificationOptions (line 3) | interface NotificationOptions {

FILE: packages/graphql-playground-electron/src/main/types.ts
  type WindowContext (line 3) | interface WindowContext {

FILE: packages/graphql-playground-electron/src/main/updates.ts
  function send (line 89) | function send(channel: string, arg: string) {
  function getBetaUpdates (line 99) | function getBetaUpdates(settingsString: string | undefined): boolean {

FILE: packages/graphql-playground-electron/src/renderer/components/App.tsx
  type State (line 53) | interface State {
  function pushSelectedFile (line 78) | function pushSelectedFile() {
  function pushOpenUrl (line 85) | function pushOpenUrl() {
  type ReduxProps (line 92) | interface ReduxProps {
  class App (line 105) | class App extends React.Component<ReduxProps, State> {
    method constructor (line 108) | constructor(props) {
    method getArgs (line 126) | getArgs(): any {
    method componentDidMount (line 237) | componentDidMount() {
    method consumeEvents (line 260) | consumeEvents() {
    method componentWillUnmount (line 272) | componentWillUnmount() {
    method configContainsEndpoints (line 383) | configContainsEndpoints(config: GraphQLConfigData): boolean {
    method openFile (line 421) | async openFile(fileName: string) {
    method showOpenDialog (line 433) | showOpenDialog() {
    method getSaveFileName (line 452) | getSaveFileName(): Promise<string> {
    method getGraphcoolYml (line 519) | getGraphcoolYml(from: string): { ymlPath: string; yml: any } | null {
    method getGraphcoolRc (line 536) | getGraphcoolRc(): any | null {
    method render (line 580) | render() {

FILE: packages/graphql-playground-electron/src/renderer/components/InitialView/InitialView.tsx
  type StateFromProps (line 16) | interface StateFromProps {
  type State (line 20) | interface State {
  type Props (line 25) | interface Props {
  class InitialView (line 57) | class InitialView extends React.Component<Props & StateFromProps, State> {
    method render (line 112) | render() {

FILE: packages/graphql-playground-electron/src/renderer/components/InitialView/Toggle.tsx
  type ToggleProps (line 4) | interface ToggleProps {

FILE: packages/graphql-playground-electron/src/renderer/components/Loading.tsx
  type Props (line 3) | interface Props {
  class Loading (line 10) | class Loading extends React.Component<Props, {}> {
    method render (line 11) | render() {

FILE: packages/graphql-playground-electron/src/renderer/components/Root.tsx
  class Root (line 6) | class Root extends React.Component {
    method render (line 7) | render() {

FILE: packages/graphql-playground-electron/src/renderer/redux/actions/history.ts
  type SELECT_HISTORY (line 1) | type SELECT_HISTORY = 'select history'
  constant SELECT_HISTORY (line 2) | const SELECT_HISTORY: SELECT_HISTORY = 'select history'
  type SelectHistoryAction (line 4) | interface SelectHistoryAction {
  type History (line 9) | interface History {

FILE: packages/graphql-playground-electron/src/renderer/redux/reducers/history.ts
  type HistoryAction (line 7) | type HistoryAction = SelectHistoryAction
  type State (line 9) | interface State {
  function historyReducer (line 17) | function historyReducer(

FILE: packages/graphql-playground-electron/src/renderer/utils/errify.ts
  function errify (line 3) | function errify(error: Error | string) {

FILE: packages/graphql-playground-electron/src/shared/utils.ts
  function createRemoteWindow (line 14) | function createRemoteWindow() {

FILE: packages/graphql-playground-electron/typings/custom.d.ts
  type Window (line 1) | interface Window {

FILE: packages/graphql-playground-electron/typings/styled-jsx.d.ts
  type HTMLProps (line 4) | interface HTMLProps<T> {
  type StyleHTMLAttributes (line 11) | interface StyleHTMLAttributes<T> extends React.HTMLAttributes<T> {

FILE: packages/graphql-playground-html/examples/xss-attack/index.js
  constant PORT (line 20) | const PORT = 4000
  method get (line 42) | async get() {

FILE: packages/graphql-playground-html/src/render-playground-page.ts
  type MiddlewareOptions (line 5) | interface MiddlewareOptions {
  type CursorShape (line 17) | type CursorShape = 'line' | 'block' | 'underline'
  type Theme (line 18) | type Theme = 'dark' | 'light'
  type ISettings (line 20) | interface ISettings {
  type EditorColours (line 36) | interface EditorColours {
  type IntrospectionResult (line 60) | interface IntrospectionResult {
  type RenderPageOptions (line 64) | interface RenderPageOptions extends MiddlewareOptions {
  type Tab (line 72) | interface Tab {
  constant CONFIG_ID (line 93) | const CONFIG_ID = 'playground-config';
  function renderPlaygroundPage (line 116) | function renderPlaygroundPage(options: RenderPageOptions) {

FILE: packages/graphql-playground-middleware-express/examples/basic/index.js
  constant PORT (line 19) | const PORT = 4000

FILE: packages/graphql-playground-middleware-express/examples/graphcool/index.js
  constant PORT (line 18) | const PORT = 4001;

FILE: packages/graphql-playground-middleware-express/src/index.ts
  type ExpressPlaygroundMiddleware (line 9) | type ExpressPlaygroundMiddleware = (
  type Register (line 15) | type Register = (

FILE: packages/graphql-playground-middleware-hapi/examples/basic/index.js
  constant HOST (line 6) | const HOST = 'localhost'
  constant PORT (line 7) | const PORT = 4000
  function start (line 33) | async function start() {

FILE: packages/graphql-playground-middleware-hapi/src/index.ts
  type Register (line 8) | interface Register {

FILE: packages/graphql-playground-middleware-koa/examples/basic/index.js
  constant PORT (line 25) | const PORT = 4000

FILE: packages/graphql-playground-middleware-koa/src/index.ts
  type KoaPlaygroundMiddlewareOptions (line 7) | type KoaPlaygroundMiddlewareOptions = MiddlewareOptions
  type KoaPlaygroundMiddleware (line 10) | type KoaPlaygroundMiddleware = (ctx: Context, next: Next) => Promise<void>
  type Register (line 12) | type Register = (options: KoaPlaygroundMiddlewareOptions) => KoaPlaygrou...

FILE: packages/graphql-playground-middleware-lambda/examples/basic/handler.js
  method posts (line 22) | posts() {
  function callbackFilter (line 29) | function callbackFilter(error, output) {

FILE: packages/graphql-playground-middleware-lambda/src/index.ts
  function lambdaPlayground (line 7) | function lambdaPlayground(options: MiddlewareOptions) {

FILE: packages/graphql-playground-react/config/env.js
  constant NODE_ENV (line 10) | const NODE_ENV = process.env.NODE_ENV;
  constant REACT_APP (line 58) | const REACT_APP = /^REACT_APP_/i;
  function getClientEnvironment (line 60) | function getClientEnvironment(publicUrl) {

FILE: packages/graphql-playground-react/config/jest/cssTransform.js
  method process (line 5) | process() {
  method getCacheKey (line 8) | getCacheKey(fileData, filename) {

FILE: packages/graphql-playground-react/config/jest/fileTransform.js
  method process (line 7) | process(src, filename) {

FILE: packages/graphql-playground-react/config/jest/typescriptTransform.js
  method process (line 6) | process(src, path) {

FILE: packages/graphql-playground-react/config/paths.js
  function ensureSlash (line 14) | function ensureSlash(path, needsSlash) {
  function getServedPath (line 34) | function getServedPath(appPackageJson) {

FILE: packages/graphql-playground-react/config/webpackDevServer.config.js
  method setup (line 84) | setup(app) {

FILE: packages/graphql-playground-react/scripts/build.js
  function removeFileNameHash (line 38) | function removeFileNameHash(fileName) {
  function getDifferenceLabel (line 46) | function getDifferenceLabel(currentSize, previousSize) {
  function printFileSizes (line 85) | function printFileSizes(stats, previousSizeMap) {
  function printErrors (line 119) | function printErrors(summary, errors) {
  function build (line 129) | function build(previousSizeMap) {
  function copyPublicFolder (line 225) | function copyPublicFolder() {

FILE: packages/graphql-playground-react/scripts/start.js
  constant DEFAULT_PORT (line 50) | const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000;
  constant HOST (line 51) | const HOST = process.env.HOST || '0.0.0.0';

FILE: packages/graphql-playground-react/src/components/Button.tsx
  type Props (line 5) | interface Props {
  type ButtonProps (line 19) | interface ButtonProps {

FILE: packages/graphql-playground-react/src/components/Copy.tsx
  type Props (line 5) | interface Props {
  type State (line 11) | interface State {
  class Copy (line 15) | class Copy extends React.Component<Props, State> {
    method constructor (line 18) | constructor(props) {
    method componentWillUnmount (line 26) | componentWillUnmount() {
    method render (line 30) | render() {

FILE: packages/graphql-playground-react/src/components/EndpointPopup.tsx
  type Props (line 13) | interface Props {
  type State (line 18) | interface State {
  class EndpointPopup (line 23) | class EndpointPopup extends React.Component<Props, State> {
    method constructor (line 80) | constructor(props) {
    method componentDidMount (line 87) | componentDidMount() {
    method render (line 91) | render() {
  type InputProps (line 160) | interface InputProps {

FILE: packages/graphql-playground-react/src/components/FileEditor.tsx
  type Props (line 10) | interface Props {
  class FileEditor (line 15) | class FileEditor extends React.Component<Props, {}> {
    method render (line 16) | render() {

FILE: packages/graphql-playground-react/src/components/GraphQLBinApp.tsx
  function getParameterByName (line 13) | function getParameterByName(name: string): string {
  type Props (line 24) | interface Props {
  type State (line 32) | interface State {
  type ReduxProps (line 40) | interface ReduxProps {
  class GraphQLBinApp (line 44) | class GraphQLBinApp extends React.Component<Props & ReduxProps, State> {
    method constructor (line 45) | constructor(props: Props & ReduxProps) {
    method UNSAFE_componentWillMount (line 56) | UNSAFE_componentWillMount() {
    method render (line 113) | render() {
  class GraphQLBinAppHOC (line 156) | class GraphQLBinAppHOC extends React.Component<Props> {
    method render (line 157) | render() {

FILE: packages/graphql-playground-react/src/components/HistoryPopup.tsx
  type ReduxProps (line 21) | interface ReduxProps {
  type State (line 29) | interface State {
  class HistoryPopup (line 35) | class HistoryPopup extends React.Component<ReduxProps, State> {
    method constructor (line 36) | constructor(props: ReduxProps) {
    method render (line 45) | render() {

FILE: packages/graphql-playground-react/src/components/HistoryPopup/HistoryChooser.tsx
  type Props (line 6) | interface Props {
  type FilterProps (line 57) | interface FilterProps {

FILE: packages/graphql-playground-react/src/components/HistoryPopup/HistoryHeader.tsx
  type Props (line 7) | interface Props {

FILE: packages/graphql-playground-react/src/components/HistoryPopup/HistoryItems.tsx
  type Props (line 7) | interface Props {
  type ItemProps (line 79) | interface ItemProps {

FILE: packages/graphql-playground-react/src/components/Icons/index.tsx
  type IProps (line 3) | interface IProps {

FILE: packages/graphql-playground-react/src/components/MiddlewareApp.tsx
  class MiddlewareApp (line 10) | class MiddlewareApp extends React.Component<
    method componentDidMount (line 13) | componentDidMount() {
    method render (line 19) | render() {

FILE: packages/graphql-playground-react/src/components/Modal.tsx
  type Props (line 5) | interface Props {

FILE: packages/graphql-playground-react/src/components/Playground.tsx
  type Response (line 56) | interface Response {
  type Props (line 62) | interface Props {
  type ReduxProps (line 98) | interface ReduxProps {
  type State (line 131) | interface State {
  type CursorPosition (line 135) | interface CursorPosition {
  class Playground (line 142) | class Playground extends React.PureComponent<Props & ReduxProps, State> {
    method constructor (line 183) | constructor(props: Props & ReduxProps) {
    method UNSAFE_componentWillMount (line 207) | UNSAFE_componentWillMount() {
    method componentDidMount (line 214) | componentDidMount() {
    method UNSAFE_componentWillReceiveProps (line 223) | UNSAFE_componentWillReceiveProps(nextProps: Props & ReduxProps) {
    method schemaGetter (line 266) | async schemaGetter(propsInput?: Props & ReduxProps) {
    method render (line 318) | render() {
    method renderHistoryPopup (line 354) | renderHistoryPopup() {
    method updateSchema (line 395) | private updateSchema(
    method httpApiPrefix (line 415) | get httpApiPrefix() {

FILE: packages/graphql-playground-react/src/components/Playground/ConfigEditor.tsx
  type Props (line 5) | interface Props {
  class ConfigEditor (line 18) | class ConfigEditor extends React.Component<Props, {}> {
    method constructor (line 24) | constructor(props) {
    method componentDidMount (line 33) | componentDidMount() {
    method componentDidUpdate (line 106) | componentDidUpdate(prevProps) {
    method componentWillUnmount (line 121) | componentWillUnmount() {
    method render (line 127) | render() {
    method getCodeMirror (line 143) | getCodeMirror() {
    method getClientHeight (line 150) | getClientHeight() {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/Argument.tsx
  type Props (line 5) | interface Props {
  function Argument (line 13) | function Argument({

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/ArgumentInline.tsx
  type Props (line 5) | interface Props {
  function Argument (line 10) | function Argument({ arg, showDefaultValue }: Props) {
  function renderType (line 29) | function renderType(type) {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/ColumnDoc.tsx
  type Props (line 5) | interface Props {
  type ColumnProps (line 25) | interface ColumnProps {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/DocTypeSchema.tsx
  type DocTypeSchemaProps (line 6) | interface DocTypeSchemaProps {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/DocsTypes/EnumTypeSchema.tsx
  type EnumTypeSchemaProps (line 5) | interface EnumTypeSchemaProps {
  type ValueProps (line 39) | interface ValueProps {
  type DocsValueProps (line 57) | interface DocsValueProps {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/DocsTypes/ScalarType.tsx
  type ScalarTypeSchemaProps (line 4) | interface ScalarTypeSchemaProps {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/DocsTypes/UnionTypeSchema.tsx
  type EnumTypeSchemaProps (line 5) | interface EnumTypeSchemaProps {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/FieldDoc.tsx
  type Props (line 19) | interface Props {
  type State (line 26) | interface State {
  class FieldDoc (line 30) | class FieldDoc extends React.Component<Props, State> {
    method componentDidMount (line 34) | componentDidMount() {
    method shouldComponentUpdate (line 38) | shouldComponentUpdate(nextProps) {
    method scrollToRight (line 46) | scrollToRight() {
    method render (line 58) | render() {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/GraphDocs.tsx
  type StateFromProps (line 30) | interface StateFromProps {
  type DispatchFromProps (line 39) | interface DispatchFromProps {
  type State (line 47) | interface State {
  class GraphDocs (line 52) | class GraphDocs extends React.Component<
    method constructor (line 59) | constructor(props) {
    method UNSAFE_componentWillReceiveProps (line 68) | UNSAFE_componentWillReceiveProps(nextProps: SideTabContentProps & Stat...
    method setWidth (line 81) | setWidth(props: any = this.props) {
    method getWidth (line 85) | getWidth(props: any = this.props) {
    method componentDidMount (line 94) | componentDidMount() {
    method render (line 98) | render() {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/GraphDocsRoot.tsx
  type Props (line 7) | interface Props {
  class GraphDocsRoot (line 12) | class GraphDocsRoot extends React.PureComponent<Props, {}> {
    method render (line 13) | render() {
  type ShowRootTypeProps (line 45) | interface ShowRootTypeProps {
  function ShowRootType (line 52) | function ShowRootType({ name, fields, offset }: ShowRootTypeProps) {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/RootColumn.tsx
  type Props (line 8) | interface Props {
  class RootColumn (line 16) | class RootColumn extends React.PureComponent<Props, {}> {
    method render (line 17) | render() {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/SchemaDoc.tsx
  type Props (line 14) | interface Props {
  class SchemaDoc (line 20) | class SchemaDoc extends React.Component<Props, {}> {
    method shouldComponentUpdate (line 21) | shouldComponentUpdate(nextProps) {
    method render (line 25) | render() {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/SearchBox.tsx
  type Props (line 6) | interface Props {
  type State (line 12) | interface State {
  class SearchBox (line 16) | class SearchBox extends React.Component<Props, State> {
    method constructor (line 19) | constructor(props) {
    method shouldComponentUpdate (line 29) | shouldComponentUpdate(nextProps, nextState) {
    method render (line 33) | render() {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/SearchResults.tsx
  type Props (line 5) | interface Props {
  class SearchResults (line 13) | class SearchResults extends React.Component<Props, {}> {
    method shouldComponentUpdate (line 14) | shouldComponentUpdate(nextProps) {
    method render (line 21) | render() {
  function isMatch (line 130) | function isMatch(sourceText, searchValue) {

FILE: packages/graphql-playground-react/src/components/Playground/DocExplorer/TypeLink.tsx
  type ReduxProps (line 17) | interface ReduxProps {
  type DispatchFromProps (line 22) | interface DispatchFromProps {
  type Props (line 26) | interface Props {
  type State (line 43) | interface State {
  class TypeLink (line 47) | class TypeLink extends React.Component<
    method constructor (line 57) | constructor(props) {
    method shouldComponentUpdate (line 64) | shouldComponentUpdate(nextProps: Props & ReduxProps, nextState: State) {
    method componentDidMount (line 84) | componentDidMount() {
    method componentDidUpdate (line 88) | componentDidUpdate() {
    method updateSize (line 92) | updateSize() {
    method render (line 114) | render() {
  function renderType (line 186) | function renderType(type) {
  type DocsCategoryItemProps (line 245) | interface DocsCategoryItemProps {

FILE: packages/graphql-playground-react/src/components/Playground/EditorWrapper.tsx
  function lintMessage (line 884) | function lintMessage(e) {
  class Container (line 916) | class Container extends React.PureComponent {
    method render (line 919) | render() {

FILE: packages/graphql-playground-react/src/components/Playground/ExecuteButton.tsx
  type ReduxProps (line 22) | interface ReduxProps {
  type State (line 30) | interface State {
  class ExecuteButton (line 43) | class ExecuteButton extends React.Component<ReduxProps, State> {
    method constructor (line 44) | constructor(props) {
    method render (line 53) | render() {
  type ButtonProps (line 203) | interface ButtonProps {

FILE: packages/graphql-playground-react/src/components/Playground/ExecuteButtonOperation.tsx
  type Props (line 3) | interface Props {
  class ExecuteButtonOperation (line 11) | class ExecuteButtonOperation extends React.PureComponent<Props> {
    method render (line 12) | render() {

FILE: packages/graphql-playground-react/src/components/Playground/ExplorerTabs/SideTab.tsx
  type Props (line 4) | interface Props {
  class SideTab (line 13) | class SideTab extends React.PureComponent<Props> {
    method render (line 14) | render() {
  type TabProps (line 29) | interface TabProps {

FILE: packages/graphql-playground-react/src/components/Playground/ExplorerTabs/SideTabs.tsx
  type StateFromProps (line 20) | interface StateFromProps {
  type DispatchFromProps (line 30) | interface DispatchFromProps {
  type Props (line 38) | interface Props {
  type SideTabContentProps (line 47) | interface SideTabContentProps {
  type State (line 54) | interface State {
  class SideTabs (line 59) | class SideTabs extends React.Component<
    method constructor (line 67) | constructor(props) {
    method componentDidUpdate (line 72) | componentDidUpdate(prevProps) {
    method componentDidMount (line 92) | componentDidMount() {
    method render (line 99) | render() {
  type TabsProps (line 279) | interface TabsProps {

FILE: packages/graphql-playground-react/src/components/Playground/GraphQLEditor.tsx
  type Props (line 77) | interface Props {
  type ReduxProps (line 84) | interface ReduxProps {
  type SimpleProps (line 123) | interface SimpleProps {
  type ToolbarButtonProps (line 127) | interface ToolbarButtonProps extends SimpleProps {
  class GraphQLEditor (line 133) | class GraphQLEditor extends React.PureComponent<Props & ReduxProps> {
    method componentDidMount (line 149) | componentDidMount() {
    method componentDidUpdate (line 159) | componentDidUpdate() {
    method render (line 173) | render() {
    method autoCompleteLeafs (line 367) | autoCompleteLeafs() {
    method didClickDragBar (line 469) | private didClickDragBar(event) {
  type DrawerProps (line 679) | interface DrawerProps {
  type TitleProps (line 692) | interface TitleProps {
  type QueryProps (line 756) | interface QueryProps {

FILE: packages/graphql-playground-react/src/components/Playground/QueryEditor.tsx
  type Props (line 38) | interface Props {
  type ReduxProps (line 46) | interface ReduxProps {
  class QueryEditor (line 60) | class QueryEditor extends React.PureComponent<Props & ReduxProps, {}> {
    method constructor (line 66) | constructor(props) {
    method componentDidMount (line 78) | componentDidMount() {
    method componentDidUpdate (line 177) | componentDidUpdate(prevProps) {
    method UNSAFE_componentWillReceiveProps (line 210) | UNSAFE_componentWillReceiveProps(nextProps) {
    method scrollTo (line 220) | scrollTo(y) {
    method updateSessionScrollTop (line 224) | updateSessionScrollTop() {
    method componentWillUnmount (line 233) | componentWillUnmount() {
    method render (line 241) | render() {
    method getCodeMirror (line 257) | getCodeMirror() {
    method getClientHeight (line 264) | getClientHeight() {

FILE: packages/graphql-playground-react/src/components/Playground/ResponseTracing.tsx
  type TracingFormat (line 14) | interface TracingFormat {
  type ReduxProps (line 31) | interface ReduxProps {
  type Props (line 69) | interface Props {
  class ResponseTracing (line 73) | class ResponseTracing extends React.PureComponent<ReduxProps & Props> {
    method render (line 74) | render() {

FILE: packages/graphql-playground-react/src/components/Playground/ResultViewer.tsx
  type Props (line 12) | interface Props {
  class ResultViewer (line 28) | class ResultViewer extends React.Component<Props, {}> {
    method componentDidMount (line 32) | componentDidMount() {
    method shouldComponentUpdate (line 79) | shouldComponentUpdate(nextProps) {
    method componentDidUpdate (line 83) | componentDidUpdate() {
    method componentWillUnmount (line 88) | componentWillUnmount() {
    method render (line 92) | render() {
    method getCodeMirror (line 106) | getCodeMirror() {
    method getClientHeight (line 113) | getClientHeight() {
  type ResultProps (line 118) | interface ResultProps {

FILE: packages/graphql-playground-react/src/components/Playground/Results.tsx
  type Props (line 11) | interface Props {
  type ReduxProps (line 15) | interface ReduxProps {
  type ResultWrapperProps (line 149) | interface ResultWrapperProps {

FILE: packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLEditor.tsx
  type Props (line 8) | interface Props {
  class SDLEditor (line 17) | class SDLEditor extends React.PureComponent<Props, { overflowY: boolean ...
    method constructor (line 22) | constructor(props) {
    method componentDidMount (line 36) | componentDidMount() {
    method componentDidUpdate (line 68) | componentDidUpdate(prevProps: Props) {
    method UNSAFE_componentWillReceiveProps (line 101) | UNSAFE_componentWillReceiveProps(nextProps) {
    method componentWillUnmount (line 107) | componentWillUnmount() {
    method render (line 125) | render() {
    method getCodeMirror (line 139) | getCodeMirror() {
    method getClientHeight (line 142) | getClientHeight() {

FILE: packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLHeader.tsx
  type SDLHeaderProps (line 7) | interface SDLHeaderProps {
  type State (line 11) | interface State {
  class SDLHeader (line 15) | class SDLHeader extends React.Component<SDLHeaderProps, State> {
    method constructor (line 18) | constructor(props) {
    method UNSAFE_componentWillMount (line 25) | UNSAFE_componentWillMount() {
    method componentWillUnmount (line 29) | componentWillUnmount() {
    method render (line 60) | render() {

FILE: packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLTypes/SDLDocType.tsx
  type DocTypeSchemaProps (line 5) | interface DocTypeSchemaProps {

FILE: packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLTypes/SDLFieldDoc.tsx
  type Props (line 10) | interface Props {
  type State (line 15) | interface State {
  class FieldDoc (line 19) | class FieldDoc extends React.Component<Props, State> {
    method render (line 22) | render() {

FILE: packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLTypes/SDLStyles.tsx
  type SDLColumnProps (line 21) | interface SDLColumnProps {

FILE: packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLTypes/SDLType.tsx
  type Props (line 6) | interface Props {
  class SDLType (line 15) | class SDLType extends React.Component<Props> {
    method render (line 16) | render() {
  function renderType (line 73) | function renderType(type) {
  type DocsCategoryItemProps (line 94) | interface DocsCategoryItemProps {

FILE: packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLTypes/SDLUnionType.tsx
  type EnumTypeSchemaProps (line 5) | interface EnumTypeSchemaProps {

FILE: packages/graphql-playground-react/src/components/Playground/SchemaExplorer/SDLView.tsx
  type StateFromProps (line 25) | interface StateFromProps {
  type DispatchFromProps (line 36) | interface DispatchFromProps {
  class SDLView (line 43) | class SDLView extends React.Component<
    method constructor (line 47) | constructor(props) {
    method UNSAFE_componentWillReceiveProps (line 51) | UNSAFE_componentWillReceiveProps(nextProps: SideTabContentProps & Stat...
    method setWidth (line 59) | setWidth(props: any = this.props) {
    method getWidth (line 63) | getWidth(props: any = this.props) {
    method componentDidMount (line 67) | componentDidMount() {
    method render (line 71) | render() {

FILE: packages/graphql-playground-react/src/components/Playground/SchemaFetcher.ts
  type TracingSchemaTuple (line 17) | interface TracingSchemaTuple {
  type SchemaFetchProps (line 22) | interface SchemaFetchProps {
  type LinkGetter (line 28) | type LinkGetter = (session: LinkCreatorProps) => { link: ApolloLink }
  class SchemaFetcher (line 39) | class SchemaFetcher {
    method constructor (line 68) | constructor(linkGetter: LinkGetter) {
    method fetch (line 74) | async fetch(session: SchemaFetchProps) {
    method subscribe (line 88) | subscribe(session: SchemaFetchProps, cb: (schema: GraphQLSchema) => vo...
    method refetch (line 92) | refetch(session: SchemaFetchProps) {
    method hash (line 95) | hash(session: SchemaFetchProps) {
    method getSchema (line 98) | private getSchema(data: IntrospectionQuery) {
    method fetchSchema (line 115) | private async fetchSchema(

FILE: packages/graphql-playground-react/src/components/Playground/Tab.tsx
  type Props (line 9) | interface Props {
  type ReduxProps (line 14) | interface ReduxProps {
  type State (line 20) | interface State {
  class Tab (line 25) | class Tab extends React.PureComponent<Props & ReduxProps, State> {
    method constructor (line 26) | constructor(props) {
    method render (line 35) | render() {
  type TabItemProps (line 139) | interface TabItemProps {

FILE: packages/graphql-playground-react/src/components/Playground/TabBar.tsx
  type Props (line 20) | interface Props {
  type ReduxProps (line 25) | interface ReduxProps {
  type State (line 31) | interface State {
  class TabBar (line 37) | class TabBar extends React.PureComponent<Props & ReduxProps, State> {
    method render (line 40) | render() {
  type TabsProps (line 114) | interface TabsProps {
  type PlusProps (line 125) | interface PlusProps {

FILE: packages/graphql-playground-react/src/components/Playground/TopBar/Polling.tsx
  type Props (line 4) | interface Props {
  type State (line 9) | interface State {
  class SchemaPolling (line 13) | class SchemaPolling extends React.Component<Props, State> {
    method constructor (line 15) | constructor(props) {
    method componentDidMount (line 22) | componentDidMount() {
    method componentWillUnmount (line 26) | componentWillUnmount() {
    method UNSAFE_componentWillReceiveProps (line 48) | UNSAFE_componentWillReceiveProps(nextProps: Props) {
    method render (line 52) | render() {
    method clearTimer (line 63) | private clearTimer() {

FILE: packages/graphql-playground-react/src/components/Playground/TopBar/PollingIcon.tsx
  type Props (line 5) | interface Props {

FILE: packages/graphql-playground-react/src/components/Playground/TopBar/Reload.tsx
  type Props (line 4) | interface Props {

FILE: packages/graphql-playground-react/src/components/Playground/TopBar/ReloadIcon.tsx
  type Props (line 5) | interface Props {

FILE: packages/graphql-playground-react/src/components/Playground/TopBar/SchemaReload.tsx
  type Props (line 9) | interface Props {

FILE: packages/graphql-playground-react/src/components/Playground/TopBar/TopBar.tsx
  type Props (line 28) | interface Props {
  class TopBar (line 45) | class TopBar extends React.Component<Props, {}> {
    method render (line 53) | render() {
  type UrlBarProps (line 206) | interface UrlBarProps {

FILE: packages/graphql-playground-react/src/components/Playground/TracingRow.tsx
  type TracingRowProps (line 42) | interface TracingRowProps {
  type TracingRowState (line 48) | interface TracingRowState {
  class TracingRow (line 52) | class TracingRow extends React.Component<
    method render (line 59) | render() {
    method printDuration (line 85) | private printDuration(nanoSeconds) {

FILE: packages/graphql-playground-react/src/components/Playground/VariableEditor.tsx
  type Props (line 24) | interface Props {
  type ReduxProps (line 31) | interface ReduxProps {
  class VariableEditor (line 51) | class VariableEditor extends React.PureComponent<Props & ReduxProps> {
    method constructor (line 56) | constructor(props) {
    method componentDidMount (line 68) | componentDidMount() {
    method componentDidUpdate (line 153) | componentDidUpdate(prevProps) {
    method componentWillUnmount (line 179) | componentWillUnmount() {
    method render (line 186) | render() {
    method getCodeMirror (line 200) | getCodeMirror() {
    method getClientHeight (line 207) | getClientHeight() {

FILE: packages/graphql-playground-react/src/components/Playground/onHasCompletion.tsx
  function onHasCompletion (line 18) | function onHasCompletion(cm, data, onHintInformationRender) {
  function renderType (line 139) | function renderType(type) {

FILE: packages/graphql-playground-react/src/components/Playground/util/InvalidSchemaError.ts
  class InvalidSchemaError (line 3) | class InvalidSchemaError extends Error {
    method constructor (line 4) | constructor(validationErrors: readonly GraphQLError[]) {

FILE: packages/graphql-playground-react/src/components/Playground/util/NoSchemaError.ts
  class NoSchemaError (line 1) | class NoSchemaError extends Error {
    method constructor (line 2) | constructor(endpoint: string) {

FILE: packages/graphql-playground-react/src/components/Playground/util/ageOfDate.ts
  function ageOfDate (line 1) | function ageOfDate(date: Date) {

FILE: packages/graphql-playground-react/src/components/Playground/util/createSDL.ts
  type Options (line 13) | interface Options {
  function sdlArray (line 35) | function sdlArray(schema: GraphQLSchema, options?: Options) {
  function getTypeInstance (line 50) | function getTypeInstance(type) {
  function getSDL (line 66) | function getSDL(
  function downloadSchema (line 91) | function downloadSchema(schema: GraphQLSchema, type: string) {
  function download (line 104) | function download(data: any, filename: string, mime?: string) {

FILE: packages/graphql-playground-react/src/components/Playground/util/fibonacci-backoff.ts
  class Backoff (line 10) | class Backoff {
    method constructor (line 16) | constructor(cb) {
    method start (line 19) | async start() {

FILE: packages/graphql-playground-react/src/components/Playground/util/getQueryFacts.ts
  function getQueryFacts (line 17) | function getQueryFacts(schema, documentAST: DocumentNode): any {
  function collectVariables (line 34) | function collectVariables(schema, documentAST) {

FILE: packages/graphql-playground-react/src/components/Playground/util/getSelectedOperationName.ts
  function getSelectedOperationName (line 13) | function getSelectedOperationName(

FILE: packages/graphql-playground-react/src/components/Playground/util/getWorkspaceId.ts
  function getWorkspaceId (line 1) | function getWorkspaceId(props: {

FILE: packages/graphql-playground-react/src/components/Playground/util/hasSubscription.ts
  function isSubscription (line 4) | function isSubscription(operation: Operation): boolean {
  function getSelectedOperation (line 12) | function getSelectedOperation(

FILE: packages/graphql-playground-react/src/components/Playground/util/immutableMemoize.ts
  function immutableMemoize (line 3) | function immutableMemoize(fn) {

FILE: packages/graphql-playground-react/src/components/Playground/util/makeOperation.ts
  type GraphQLRequestData (line 5) | interface GraphQLRequestData {
  function makeOperation (line 12) | function makeOperation(request: GraphQLRequestData): Operation {

FILE: packages/graphql-playground-react/src/components/Playground/util/parseHeaders.ts
  function parseHeaders (line 1) | function parseHeaders(headers?: string) {

FILE: packages/graphql-playground-react/src/components/Playground/util/session.ts
  function isSharingAuthorization (line 3) | function isSharingAuthorization(sharableSessions: Session[]): boolean {

FILE: packages/graphql-playground-react/src/components/Playground/util/shallowEqual.ts
  function is (line 3) | function is(x, y) {
  function shallowEqual (line 11) | function shallowEqual(objA, objB) {

FILE: packages/graphql-playground-react/src/components/Playground/util/stack.ts
  function getNewStack (line 4) | function getNewStack(root, schema, stack: Map<any, any>) {
  function getDeeperType (line 54) | function getDeeperType(type: any, depth: number = 0): any {
  type SerializedRoot (line 61) | interface SerializedRoot {
  function getRootMap (line 67) | function getRootMap(schema): any {
  function serializeRoot (line 80) | function serializeRoot(schema): SerializedRoot {
  function getElementRoot (line 120) | function getElementRoot(obj: any, index: number) {
  type SerializedObj (line 135) | interface SerializedObj {
  function serialize (line 142) | function serialize(schema, field) {
  function getElement (line 178) | function getElement(obj: any, index: number) {
  function getElementIndex (line 197) | function getElementIndex(schema: any, main: any, element: any) {

FILE: packages/graphql-playground-react/src/components/Playground/util/whatChanged.ts
  function whatChanged (line 1) | function whatChanged(
  function getUnequalProps (line 13) | function getUnequalProps(obj1, obj2) {

FILE: packages/graphql-playground-react/src/components/PlaygroundWrapper.tsx
  function getParameterByName (line 30) | function getParameterByName(name: string, uri?: string): string | null {
  type PlaygroundWrapperProps (line 41) | interface PlaygroundWrapperProps {
  type ReduxProps (line 73) | interface ReduxProps {
  type State (line 78) | interface State {
  class PlaygroundWrapper (line 92) | class PlaygroundWrapper extends React.Component<
    method constructor (line 97) | constructor(props: PlaygroundWrapperProps & ReduxProps) {
    method mapPropsToState (line 105) | mapPropsToState(props: PlaygroundWrapperProps): State {
    method extractEndpointAndHeaders (line 150) | extractEndpointAndHeaders(endpoint) {
    method removeLoader (line 166) | removeLoader() {
    method normalizeSubscriptionUrl (line 173) | normalizeSubscriptionUrl(endpoint, subscriptionEndpoint) {
    method getGraphcoolSubscriptionEndpoint (line 192) | getGraphcoolSubscriptionEndpoint(endpoint) {
    method UNSAFE_componentWillReceiveProps (line 202) | UNSAFE_componentWillReceiveProps(nextProps: PlaygroundWrapperProps & R...
    method getInitialActiveEnv (line 217) | getInitialActiveEnv(
    method isConfigYaml (line 241) | isConfigYaml(configString: string) {
    method absolutizeUrl (line 251) | absolutizeUrl(url) {
    method UNSAFE_componentWillMount (line 259) | UNSAFE_componentWillMount() {
    method componentDidMount (line 267) | componentDidMount() {
    method setInitialWorkspace (line 306) | setInitialWorkspace(props = this.props) {
    method removePlaygroundInClass (line 329) | removePlaygroundInClass() {
    method render (line 336) | render() {
    method getTitle (line 461) | private getTitle() {
    method updateSubscriptionsUrl (line 476) | private async updateSubscriptionsUrl() {
    method getSubscriptionsUrlCandidated (line 486) | private getSubscriptionsUrlCandidated(endpoint): string[] {
    method wsEndpointValid (line 504) | private wsEndpointValid(url): Promise<boolean> {
    method getProjectId (line 525) | private getProjectId(endpoint) {
  function find (line 541) | async function find(

FILE: packages/graphql-playground-react/src/components/Popup.tsx
  type Props (line 5) | interface Props {
  class Popup (line 37) | class Popup extends React.Component<Props, {}> {
    method render (line 38) | render() {

FILE: packages/graphql-playground-react/src/components/ProjectsSideNav.tsx
  type Props (line 14) | interface Props {
  type ReduxProps (line 27) | interface ReduxProps {
  class ProjectsSideNav (line 32) | class ProjectsSideNav extends React.Component<Props & ReduxProps, {}> {
    method render (line 33) | render() {
    method renderEndpoints (line 79) | private renderEndpoints(

FILE: packages/graphql-playground-react/src/components/ProjectsSideNavItem.tsx
  type Props (line 4) | interface Props {
  class ProjectsSideNavItem (line 14) | class ProjectsSideNavItem extends React.Component<Props, {}> {
    method render (line 15) | render() {
  type SidebarItemProps (line 39) | interface SidebarItemProps {

FILE: packages/graphql-playground-react/src/components/Root.tsx
  class Root (line 5) | class Root extends React.Component<{}, {}> {
    method render (line 6) | render() {

FILE: packages/graphql-playground-react/src/components/Settings.tsx
  type Props (line 7) | interface Props {
  class Settings (line 11) | class Settings extends React.Component<Props, {}> {
    method render (line 12) | render() {

FILE: packages/graphql-playground-react/src/components/SettingsEditor.tsx
  type Props (line 13) | interface Props {
  class SettingsEditor (line 24) | class SettingsEditor extends React.Component<Props, {}> {
    method componentDidMount (line 25) | componentDidMount() {
    method render (line 29) | render() {
  type HOCProps (line 67) | interface HOCProps {
  class SettingsEditorHOC (line 74) | class SettingsEditorHOC extends React.Component<
    method constructor (line 78) | constructor(props) {
    method UNSAFE_componentWillReceiveProps (line 82) | UNSAFE_componentWillReceiveProps(nextProps) {
    method render (line 87) | render() {

FILE: packages/graphql-playground-react/src/components/Share.tsx
  type SharingProps (line 23) | interface SharingProps {
  type State (line 40) | interface State {
  class Share (line 44) | class Share extends React.Component<SharingProps, State> {
    method constructor (line 45) | constructor(props) {
    method render (line 51) | render() {

FILE: packages/graphql-playground-react/src/components/Toggle.tsx
  type ToggleProps (line 4) | interface ToggleProps {
  type ChoiceProps (line 33) | interface ChoiceProps {

FILE: packages/graphql-playground-react/src/components/ToggleButton.tsx
  type Props (line 4) | interface Props {
  type SliderProps (line 33) | interface SliderProps {

FILE: packages/graphql-playground-react/src/components/Tooltip.tsx
  type Props (line 5) | interface Props {
  class Tooltip (line 17) | class Tooltip extends React.PureComponent<Props, {}> {
    method componentDidMount (line 25) | componentDidMount() {
    method componentWillUnmount (line 29) | componentWillUnmount() {
    method render (line 56) | render() {
  type WrapperProps (line 81) | interface WrapperProps {

FILE: packages/graphql-playground-react/src/components/asyncComponent.tsx
  type State (line 4) | interface State {
  method componentDidMount (line 13) | componentDidMount() {
  method render (line 19) | render() {

FILE: packages/graphql-playground-react/src/components/resolveRefStrings.ts
  function resolveRefString (line 1) | function resolveRefString(str: string, values?: object): string {
  function resolveEnvsInValues (line 14) | function resolveEnvsInValues<T extends any>(
  function getUsedEnvs (line 30) | function getUsedEnvs(config: any): { [name: string]: string } {
  function parseRef (line 49) | function parseRef(rawRef: string): { type: string; ref: string } {
  function resolveRef (line 54) | function resolveRef(
  function parse (line 83) | function parse(str: string): { strings: string[]; rawRefs: string[] } {

FILE: packages/graphql-playground-react/src/components/util.ts
  function getActiveEndpoints (line 5) | function getActiveEndpoints(
  function getEndpointFromEndpointConfig (line 19) | function getEndpointFromEndpointConfig(
  function cachedPrintSchema (line 43) | function cachedPrintSchema(schema: GraphQLSchema) {

FILE: packages/graphql-playground-react/src/constants.ts
  function getDefaultSession (line 36) | function getDefaultSession(endpoint: string) {

FILE: packages/graphql-playground-react/src/graphqlConfig.ts
  type GraphQLConfigExtensions (line 1) | interface GraphQLConfigExtensions {
  type GraphQLResolvedConfigData (line 6) | interface GraphQLResolvedConfigData {
  type GraphQLConfig (line 15) | type GraphQLConfig = GraphQLResolvedConfigData & {
  type GraphQLConfigEnpointsSubscription (line 19) | interface GraphQLConfigEnpointsSubscription {
  type GraphQLConfigEnpointConfig (line 24) | interface GraphQLConfigEnpointConfig {
  type GraphQLConfigEnpointsMapData (line 30) | interface GraphQLConfigEnpointsMapData {
  type GraphQLConfigEnpointsMap (line 34) | interface GraphQLConfigEnpointsMap {
  type GraphQLConfigEnpointsData (line 38) | type GraphQLConfigEnpointsData = GraphQLConfigEnpointsMapData

FILE: packages/graphql-playground-react/src/index.tsx
  method init (line 14) | init(element: HTMLElement, options) {

FILE: packages/graphql-playground-react/src/localDevIndex.tsx
  method init (line 19) | init(element: HTMLElement, options) {

FILE: packages/graphql-playground-react/src/middlewareIndex.tsx
  method init (line 14) | init(element: HTMLElement, options) {

FILE: packages/graphql-playground-react/src/setupEnzyme.ts
  method beforeParse (line 10) | beforeParse(window) {
  function copyProps (line 16) | function copyProps(src, target) {

FILE: packages/graphql-playground-react/src/state/appHistory/reducers.ts
  class AppHistory (line 6) | class AppHistory extends Record({
  class AppHistoryItem (line 12) | class AppHistoryItem extends Record({

FILE: packages/graphql-playground-react/src/state/docs/reducers.ts
  type DocsState (line 6) | type DocsState = Map<string, DocsSessionState>
  type NavItem (line 8) | interface NavItem {
  type DocsSessionState (line 14) | interface DocsSessionState {
  class DocsSession (line 22) | class DocsSession extends Record({
    method toJSON (line 29) | toJSON() {
  function getSession (line 103) | function getSession(state, sessionId) {

FILE: packages/graphql-playground-react/src/state/general/reducers.ts
  class GeneralState (line 4) | class GeneralState extends Record({

FILE: packages/graphql-playground-react/src/state/history/reducers.ts
  type HistoryState (line 6) | type HistoryState = OrderedMap<string, SessionStateProps>

FILE: packages/graphql-playground-react/src/state/localStorage.ts
  function serializeState (line 4) | function serializeState(store) {
  function deserializeState (line 17) | function deserializeState() {

FILE: packages/graphql-playground-react/src/state/sessions/WebSocketLink.ts
  class WebSocketLink (line 5) | class WebSocketLink extends ApolloLink {
    method constructor (line 7) | constructor(private client: Client) {
    method request (line 11) | public request(operation: Operation): Observable<FetchResult> {

FILE: packages/graphql-playground-react/src/state/sessions/actions.ts
  function simpleAction (line 195) | function simpleAction(key?: any, defaultValue?: any) {

FILE: packages/graphql-playground-react/src/state/sessions/fetchingSagas.ts
  function setSubscriptionEndpoint (line 47) | function setSubscriptionEndpoint(endpoint) {
  type LinkCreatorProps (line 51) | interface LinkCreatorProps {
  type Headers (line 58) | interface Headers {
  function setLinkCreator (line 139) | function setLinkCreator(newLinkCreator) {
  function formatError (line 275) | function formatError(error, fetchingSchema: boolean = false) {
  function extractMessage (line 292) | function extractMessage(error) {

FILE: packages/graphql-playground-react/src/state/sessions/reducers.ts
  type SessionStateProps (line 31) | interface SessionStateProps {
  type Tab (line 38) | interface Tab {
  class Session (line 48) | class Session extends Record(getDefaultSession('')) {
    method toJSON (line 103) | toJSON() {
  type VariableToType (line 121) | type VariableToType = Map<string, any>
  type QueryTypes (line 123) | interface QueryTypes {
  type OperationDefinition (line 130) | interface OperationDefinition {
  type ResponseType (line 135) | interface ResponseType {
  class ResponseRecord (line 141) | class ResponseRecord extends Record({
  function makeSession (line 153) | function makeSession(endpoint = '') {
  function sessionFromTab (line 157) | function sessionFromTab(tab: Tab): Session {
  class SessionState (line 168) | class SessionState extends Record({
  function makeSessionState (line 180) | function makeSessionState(endpoint) {
  function closeTab (line 600) | function closeTab(state, sessionId) {

FILE: packages/graphql-playground-react/src/state/sessions/selectors.ts
  function getSelectedWorkspaceId (line 4) | function getSelectedWorkspaceId(state) {
  function getSelectedWorkspace (line 7) | function getSelectedWorkspace(state) {
  function getSettings (line 104) | function getSettings(state) {
  function getParsedHeadersFromSession (line 146) | function getParsedHeadersFromSession(headers) {
  function getParsedVariablesFromSession (line 162) | function getParsedVariablesFromSession(session) {

FILE: packages/graphql-playground-react/src/state/sharing/reducers.ts
  class SharingState (line 4) | class SharingState extends Record({

FILE: packages/graphql-playground-react/src/state/workspace/deserialize.ts
  function deserializePersistedState (line 10) | function deserializePersistedState(state) {
  function deserializeWorkspaces (line 20) | function deserializeWorkspaces(workspaces): Map<string, any> {
  function deserializeAppHistory (line 33) | function deserializeAppHistory(state) {
  function deserializeDocs (line 39) | function deserializeDocs(state): Map<string, any> {
  function deserializeNavstack (line 52) | function deserializeNavstack(navStack) {
  function deserializeSessionsState (line 57) | function deserializeSessionsState(state) {
  function deserializeSessions (line 73) | function deserializeSessions(state) {
  function deserializeSession (line 77) | function deserializeSession(session) {
  function deserializeResponses (line 96) | function deserializeResponses(responses) {
  function deserializeResponse (line 104) | function deserializeResponse(response) {
  function deserializeSharing (line 113) | function deserializeSharing({ shareUrl, ...state }) {
  function deserializeHistory (line 118) | function deserializeHistory(state) {
  function deserializeGeneral (line 122) | function deserializeGeneral(state) {

FILE: packages/graphql-playground-react/src/state/workspace/reducers.ts
  function getSelectedWorkspaceId (line 23) | function getSelectedWorkspaceId(state) {
  function getSelectedWorkspace (line 27) | function getSelectedWorkspace(state) {
  class Workspace (line 31) | class Workspace extends Record({
  class RootState (line 65) | class RootState extends Record({
  function makeStateFromTabs (line 148) | function makeStateFromTabs(tabs: Tab[]): RootState {
  function makeWorkspace (line 168) | function makeWorkspace(endpoint) {
  function normalizeSettings (line 194) | function normalizeSettings(settings) {
  function parseSettingsString (line 206) | function parseSettingsString(settingsString) {
  function normalizeSettingsString (line 214) | function normalizeSettingsString(settingsString) {

FILE: packages/graphql-playground-react/src/styled/theme.ts
  type Colours (line 4) | interface Colours {
  type EditorColours (line 42) | interface EditorColours {
  type Sizes (line 294) | interface Sizes {
  type Shorthands (line 328) | interface Shorthands {
  type ThemeInterface (line 334) | interface ThemeInterface {

FILE: packages/graphql-playground-react/src/types.ts
  type ApolloLinkExecuteResponse (line 3) | type ApolloLinkExecuteResponse = Observable<FetchResult>
  type HistoryFilter (line 5) | type HistoryFilter = 'HISTORY' | 'STARRED'
  type Environment (line 7) | type Environment = 'Node' | 'Browser' | 'Cli'
  type GraphQLClient (line 8) | type GraphQLClient =
  type Theme (line 15) | type Theme = 'dark' | 'light'
  type CursorShape (line 17) | type CursorShape = 'line' | 'block' | 'underline'
  type ISettings (line 19) | interface ISettings {

FILE: packages/graphql-playground-react/src/utils.ts
  function safely (line 5) | function safely(cb: any) {
  type PrettierOptions (line 15) | interface PrettierOptions {
  function prettify (line 21) | function prettify(query: string, options: PrettierOptions) {
  function isIframe (line 29) | function isIframe() {

FILE: packages/graphql-playground-react/src/utils/performance.ts
  function log (line 3) | function log(...messages) {

FILE: packages/graphql-playground-react/typings/custom.d.ts
  type Window (line 1) | interface Window {

FILE: packages/graphql-playground-react/typings/styled-jsx.d.ts
  type HTMLProps (line 4) | interface HTMLProps<T> {
  type StyleHTMLAttributes (line 11) | interface StyleHTMLAttributes<T> extends React.HTMLAttributes<T> {
Condensed preview — 316 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (957K chars).
[
  {
    "path": ".dependabot/config.yml",
    "chars": 3848,
    "preview": "version: 1\nupdate_configs:\n  - package_manager: 'javascript'\n    directory: '/'\n    update_schedule: 'live'\n    allowed_"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "chars": 2280,
    "preview": "# Contributing to this project\n\n[fork]: https://github.com/graphcool/graphql-playground/fork\n[pr]: https://github.com/gr"
  },
  {
    "path": ".github/ISSUE_TEMPLATE.md",
    "chars": 694,
    "preview": "#### This issue pertains to the following package(s):\n\n- [ ] GraphQL Playground - Electron App\n- [ ] GraphQL Playground "
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 61,
    "preview": "Fixes #.\n\nChanges proposed in this pull request:\n\n- \n\n- \n\n- \n"
  },
  {
    "path": ".gitignore",
    "chars": 288,
    "preview": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modu"
  },
  {
    "path": ".nvmrc",
    "chars": 12,
    "preview": "lts/dubnium\n"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 97,
    "preview": "{\n  \"prettier.singleQuote\": true,\n  \"prettier.trailingComma\": \"all\",\n  \"prettier.semi\": false,\n}\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3213,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": "LICENSE",
    "chars": 1066,
    "preview": "MIT License\n\nCopyright (c) 2017 Graphcool\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\n"
  },
  {
    "path": "README.md",
    "chars": 16938,
    "preview": "<p align=\"center\"><img src=\"https://imgur.com/5fzMbyV.png\" width=\"269\"></p>\n\n[![npm version](https://badge.fury.io/js/gr"
  },
  {
    "path": "SECURITY.md",
    "chars": 225,
    "preview": "# Known Vulnerabilities\n\n- [2021: Introspection Schema Phishing Attack XSS Vulnerability](docs/security/2021-schema-xss-"
  },
  {
    "path": "docs/security/2020-xss-template-injection.md",
    "chars": 3635,
    "preview": "## XSS Reflection Vulnerability\n\nthe origin of the vulnerability is in `renderPlaygroundPage`, found in `graphql-playgro"
  },
  {
    "path": "docs/security/2021-schema-xss-phishing-attack.md",
    "chars": 7928,
    "preview": "## GraphQL Playground introspection schema template injection attack: Advisory Statement\n\nThis is a security advisory fo"
  },
  {
    "path": "lerna.json",
    "chars": 562,
    "preview": "{\n  \"version\": \"independent\",\n  \"packages\": [\"packages/*\"],\n  \"npmClient\": \"yarn\",\n  \"useWorkspaces\": true,\n  \"command\":"
  },
  {
    "path": "package.json",
    "chars": 563,
    "preview": "{\n  \"private\": true,\n  \"workspaces\": [\n    \"packages/*\"\n  ],\n  \"scripts\": {\n    \"build\": \"bash scripts/build.sh\",\n    \"s"
  },
  {
    "path": "packages/graphql-playground-electron/.babelrc",
    "chars": 208,
    "preview": "{\n  \"presets\": [\n    \"@babel/preset-env\", \"@babel/preset-react\"\n  ],\n  \"plugins\": [\n    \"styled-jsx-postcss/babel\",\n    "
  },
  {
    "path": "packages/graphql-playground-electron/.gitignore",
    "chars": 147,
    "preview": ".DS_STORE\n*.log\n.vscode\nnode_modules\ndist\n.tmp\nlib\n.idea\n*.iml\n*.swp\n*.swo\n.envrc\n.netlify\n.tags\n.yarnclean\n.awcache\ndll"
  },
  {
    "path": "packages/graphql-playground-electron/CHANGELOG.md",
    "chars": 7329,
    "preview": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://co"
  },
  {
    "path": "packages/graphql-playground-electron/README.md",
    "chars": 407,
    "preview": "# Playground\n\nRepository for the electron playground app.\n\n## Development\n```sh\nyarn install\nyarn start\n```\n\n## Producti"
  },
  {
    "path": "packages/graphql-playground-electron/package.json",
    "chars": 6549,
    "preview": "{\n  \"name\": \"graphql-playground-electron\",\n  \"productName\": \"GraphQL Playground\",\n  \"homepage\": \"https://github.com/grap"
  },
  {
    "path": "packages/graphql-playground-electron/postcss.config.js",
    "chars": 334,
    "preview": "module.exports = ctx => ({\n  plugins: [\n    require('postcss-simple-vars')({\n      variables: () => require('graphcool-s"
  },
  {
    "path": "packages/graphql-playground-electron/src/main/createWindow.ts",
    "chars": 2087,
    "preview": "import { BrowserWindow, app, ipcMain } from 'electron'\nimport * as path from 'path'\nimport dev = require('electron-is-de"
  },
  {
    "path": "packages/graphql-playground-electron/src/main/index.ts",
    "chars": 4275,
    "preview": "// TODO enable tslint\n// /* tslint:disable */\nimport {\n  app,\n  BrowserWindow,\n  globalShortcut,\n  ipcMain,\n  protocol,\n"
  },
  {
    "path": "packages/graphql-playground-electron/src/main/menu.ts",
    "chars": 4367,
    "preview": "import {\n  MenuItemConstructorOptions,\n  BrowserWindow,\n  app,\n  autoUpdater,\n} from 'electron'\nimport * as log from 'el"
  },
  {
    "path": "packages/graphql-playground-electron/src/main/notify.ts",
    "chars": 551,
    "preview": "import { shell, Notification } from 'electron'\n\ninterface NotificationOptions {\n  title: string\n  body: string\n  url?: s"
  },
  {
    "path": "packages/graphql-playground-electron/src/main/types.ts",
    "chars": 253,
    "preview": "import { BrowserWindow } from 'electron'\n\nexport interface WindowContext {\n  readyWindowsPromises: { [windowId: number]:"
  },
  {
    "path": "packages/graphql-playground-electron/src/main/updates.ts",
    "chars": 2731,
    "preview": "import { app, autoUpdater, ipcMain, BrowserWindow, dialog } from 'electron'\nimport ms = require('ms')\nimport dev = requi"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/components/App.tsx",
    "chars": 17677,
    "preview": "import * as React from 'react'\nimport 'core-js/stable'\nimport 'regenerator-runtime/runtime'\nimport { remote, ipcRenderer"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/components/InitialView/InitialView.tsx",
    "chars": 10871,
    "preview": "import * as React from 'react'\nimport * as isURL from 'validator/lib/isURL'\nimport { remote } from 'electron'\nimport { e"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/components/InitialView/Toggle.tsx",
    "chars": 1145,
    "preview": "import * as React from 'react'\nimport * as cn from 'classnames'\n\nexport interface ToggleProps {\n  choices: string[]\n  on"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/components/InitialView/data.ts",
    "chars": 327,
    "preview": "export const examples = [\n  {\n    name: 'Movie Database',\n    endpoint: 'https://api.graph.cool/simple/v1/cixos23120m0n0"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/components/Loading.tsx",
    "chars": 880,
    "preview": "import * as React from 'react'\n\ninterface Props {\n  color?: string\n  width?: number\n  height?: number\n  className?: stri"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/components/Root.tsx",
    "chars": 299,
    "preview": "import * as React from 'react'\nimport App from './App'\nimport { store } from 'graphql-playground-react'\nimport { Provide"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/index.css",
    "chars": 30,
    "preview": "body {\n    overflow: hidden;\n}"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/index.html",
    "chars": 18790,
    "preview": "<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=utf-8 />\n  <meta name=\"viewport\" content=\"user-scalable=no, initial-scale"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/index.tsx",
    "chars": 229,
    "preview": "import * as React from 'react'\nimport * as ReactDOM from 'react-dom'\nimport Root from './components/Root'\nimport 'graphc"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/redux/actions/history.ts",
    "chars": 401,
    "preview": "export type SELECT_HISTORY = 'select history'\nexport const SELECT_HISTORY: SELECT_HISTORY = 'select history'\n\nexport int"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/redux/createStore.ts",
    "chars": 1142,
    "preview": "import { compose, createStore } from 'redux'\nimport persistState, { mergePersistedState } from 'redux-localstorage'\nimpo"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/redux/reducers/history.ts",
    "chars": 978,
    "preview": "import {\n  SELECT_HISTORY,\n  SelectHistoryAction,\n  History,\n} from '../actions/history'\n\nexport type HistoryAction = Se"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/redux/reducers/index.ts",
    "chars": 258,
    "preview": "import { combineReducers } from 'redux'\nimport graphiqlDocs from 'graphql-playground-react/lib/reducers/graphiql-docs'\ni"
  },
  {
    "path": "packages/graphql-playground-electron/src/renderer/utils/errify.ts",
    "chars": 251,
    "preview": "import swal from 'sweetalert2'\n\nexport function errify(error: Error | string) {\n  const message = typeof error === 'stri"
  },
  {
    "path": "packages/graphql-playground-electron/src/shared/utils.ts",
    "chars": 593,
    "preview": "import { remote } from 'electron'\nimport * as dev from 'electron-is-dev'\nimport * as path from 'path'\n\nexport const newW"
  },
  {
    "path": "packages/graphql-playground-electron/tsconfig.json",
    "chars": 593,
    "preview": "{\n  \"compilerOptions\": {\n    \"removeComments\": true,\n    \"module\": \"commonjs\",\n    \"jsx\": \"react\",\n    \"sourceMap\": true"
  },
  {
    "path": "packages/graphql-playground-electron/tslint.json",
    "chars": 199,
    "preview": "{\n  \"extends\": [\n    \"tslint-graphcool-frontend\"\n  ],\n  \"rules\": {\n    \"no-console\": false,\n    \"no-implicit-dependencie"
  },
  {
    "path": "packages/graphql-playground-electron/typings/custom.d.ts",
    "chars": 126,
    "preview": "interface Window {\n  GraphQLPlayground: any\n  __REDUX_DEVTOOLS_EXTENSION__: any\n  __REDUX_DEVTOOLS_EXTENSION_COMPOSE__: "
  },
  {
    "path": "packages/graphql-playground-electron/typings/styled-jsx.d.ts",
    "chars": 253,
    "preview": "import 'react'\n\ndeclare module 'react' {\n  interface HTMLProps<T> {\n    jsx?: boolean\n    global?: boolean\n  }\n}\n\ndeclar"
  },
  {
    "path": "packages/graphql-playground-electron/webpack.config.build.js",
    "chars": 3961,
    "preview": "const webpack = require('webpack')\nconst HtmlWebpackPlugin = require('html-webpack-plugin')\nconst cssnano = require('css"
  },
  {
    "path": "packages/graphql-playground-electron/webpack.config.js",
    "chars": 2994,
    "preview": "const webpack = require('webpack')\nconst HtmlWebpackPlugin = require('html-webpack-plugin')\nconst BundleAnalyzerPlugin ="
  },
  {
    "path": "packages/graphql-playground-html/.gitignore",
    "chars": 226,
    "preview": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modu"
  },
  {
    "path": "packages/graphql-playground-html/CHANGELOG.md",
    "chars": 3955,
    "preview": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://co"
  },
  {
    "path": "packages/graphql-playground-html/README.md",
    "chars": 578,
    "preview": "# graphql-playground-html\n\n> **SECURITY WARNING:** This package and all of it's dependendents had a severe XSS Reflectio"
  },
  {
    "path": "packages/graphql-playground-html/examples/xss-attack/README.md",
    "chars": 2853,
    "preview": "# GraphQL Playground HTML XSS Reflection Attack Example\n\nThis shows the simplest possible example for how one might re-c"
  },
  {
    "path": "packages/graphql-playground-html/examples/xss-attack/index.js",
    "chars": 1832,
    "preview": "const express = require('express')\nconst { ApolloServer, gql } = require('apollo-server-express')\nconst { filterXSS } = "
  },
  {
    "path": "packages/graphql-playground-html/examples/xss-attack/package.json",
    "chars": 373,
    "preview": "{\n  \"name\": \"xss-attack\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \""
  },
  {
    "path": "packages/graphql-playground-html/minimal.html",
    "chars": 1531,
    "preview": "<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=utf-8/>\n  <meta name=\"viewport\" content=\"user-scalable=no, initial-scale="
  },
  {
    "path": "packages/graphql-playground-html/minimalWithoutCDN.html",
    "chars": 1500,
    "preview": "<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=utf-8 />\n  <meta name=\"viewport\" content=\"user-scalable=no, initial-scale"
  },
  {
    "path": "packages/graphql-playground-html/package.json",
    "chars": 1072,
    "preview": "{\n  \"name\": \"graphql-playground-html\",\n  \"version\": \"1.6.29\",\n  \"homepage\": \"https://github.com/graphcool/graphql-playgr"
  },
  {
    "path": "packages/graphql-playground-html/src/get-loading-markup.ts",
    "chars": 15568,
    "preview": "const getLoadingMarkup = () => ({\n  script: `\n    const loadingWrapper = document.getElementById('loading-wrapper');\n   "
  },
  {
    "path": "packages/graphql-playground-html/src/index.ts",
    "chars": 109,
    "preview": "export {\n  renderPlaygroundPage,\n  MiddlewareOptions,\n  RenderPageOptions,\n} from './render-playground-page'\n"
  },
  {
    "path": "packages/graphql-playground-html/src/render-playground-page.ts",
    "chars": 6151,
    "preview": "import { filterXSS } from 'xss';\n\nimport getLoadingMarkup from './get-loading-markup'\n\nexport interface MiddlewareOption"
  },
  {
    "path": "packages/graphql-playground-html/tsconfig.json",
    "chars": 408,
    "preview": "{\n  \"compilerOptions\": {\n    \"outDir\": \"dist\",\n    \"target\": \"es5\",\n    \"lib\": [\"esnext\", \"dom\"],\n    \"sourceMap\": true,"
  },
  {
    "path": "packages/graphql-playground-html/withAnimation.html",
    "chars": 19034,
    "preview": "<!DOCTYPE html>\n\n<html>\n\n<head>\n  <meta charset=utf-8 />\n  <meta name=\"viewport\" content=\"user-scalable=no, initial-scal"
  },
  {
    "path": "packages/graphql-playground-middleware-express/.gitignore",
    "chars": 226,
    "preview": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modu"
  },
  {
    "path": "packages/graphql-playground-middleware-express/CHANGELOG.md",
    "chars": 4044,
    "preview": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://co"
  },
  {
    "path": "packages/graphql-playground-middleware-express/README.md",
    "chars": 1405,
    "preview": "# graphql-playground-middleware-express\n\n> Express middleware to expose an endpoint for the GraphQL Playground IDE\n> **S"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/basic/.envrc",
    "chars": 16,
    "preview": "export PORT=4000"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/basic/.graphqlconfig.yml",
    "chars": 253,
    "preview": "schemaPath: schema.graphql\nextensions:\n  endpoints:\n    default:\n      url: 'https://airbnb.now.sh'\n      subscription: "
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/basic/README.md",
    "chars": 73,
    "preview": "# GraphQL Playground Express.js Example\n\n```sh\n$ yarn\n$ node index.js\n```"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/basic/index.js",
    "chars": 684,
    "preview": "const express = require('express')\nconst { ApolloServer, gql } = require('apollo-server-express')\nconst expressPlaygroun"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/basic/package.json",
    "chars": 362,
    "preview": "{\n  \"name\": \"basic\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"node "
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/.envrc",
    "chars": 16,
    "preview": "export PORT=4000"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/.graphqlconfig.yml",
    "chars": 386,
    "preview": "schemaPath: schema.graphql\nprojects:\n  db:\n    extensions:\n      # graphcool: graphcool.yml\n      prisma: prisma.yml\n  g"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/README.md",
    "chars": 73,
    "preview": "# GraphQL Playground Express.js Example\n\n```sh\n$ yarn\n$ node index.js\n```"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/datamodel.graphql",
    "chars": 61,
    "preview": "type User {\n  id: ID! @unique\n  name: String!\n  trolo: Int\n}\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/graphcool.yml",
    "chars": 112,
    "preview": "service: whh\nstage: dev\ncluster: workspace-asd/graphcool-eu1\n\ndatamodel:\n- datamodel.graphql\n\ndisableAuth: true\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/index.js",
    "chars": 698,
    "preview": "const express = require(\"express\");\nconst { gql, ApolloServer } = require(\"apollo-server-express\");\nconst expressPlaygro"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/package.json",
    "chars": 362,
    "preview": "{\n  \"name\": \"basic\",\n  \"version\": \"1.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"node "
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/prisma.yml",
    "chars": 109,
    "preview": "service: whh\nstage: dev\ncluster: workspace-asd/prisma-eu1\n\ndatamodel:\n- datamodel.graphql\n\ndisableAuth: true\n"
  },
  {
    "path": "packages/graphql-playground-middleware-express/examples/graphcool/schema.graphql",
    "chars": 2403,
    "preview": "# THIS FILE HAS BEEN AUTO-GENERATED BY THE \"GRAPHCOOL DEPLOY\"\n# DO NOT EDIT THIS FILE DIRECTLY\n\n#\n# Model Types\n#\n\ntype "
  },
  {
    "path": "packages/graphql-playground-middleware-express/package.json",
    "chars": 1201,
    "preview": "{\n  \"name\": \"graphql-playground-middleware-express\",\n  \"version\": \"1.7.22\",\n  \"homepage\": \"https://github.com/graphcool/"
  },
  {
    "path": "packages/graphql-playground-middleware-express/src/index.ts",
    "chars": 632,
    "preview": "import { Request, Response } from 'express'\nimport {\n  MiddlewareOptions,\n  renderPlaygroundPage,\n} from 'graphql-playgr"
  },
  {
    "path": "packages/graphql-playground-middleware-express/tsconfig.json",
    "chars": 408,
    "preview": "{\n  \"compilerOptions\": {\n    \"outDir\": \"dist\",\n    \"target\": \"es5\",\n    \"lib\": [\"esnext\", \"dom\"],\n    \"sourceMap\": true,"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/.gitignore",
    "chars": 226,
    "preview": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modu"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/CHANGELOG.md",
    "chars": 3049,
    "preview": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://co"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/README.md",
    "chars": 1517,
    "preview": "# graphql-playground-middleware-hapi\n\n> Koa middleware to expose an endpoint for the GraphQL Playground IDE\n> **SECURITY"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/examples/basic/README.md",
    "chars": 175,
    "preview": "# GraphQL Playground Hapi Example\n\n> Note: `graphql-playground-middleware-hapi` @^2.0.0 requires `hapi` 17, for `hapi` 1"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/examples/basic/index.js",
    "chars": 1110,
    "preview": "const Hapi = require('@hapi/hapi')\nconst { ApolloServer, gql } = require('apollo-server-hapi')\nconst hapiPlayground = re"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/examples/basic/package.json",
    "chars": 395,
    "preview": "{\n  \"name\": \"hapi\",\n  \"version\": \"2.0.0\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \"node i"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/package.json",
    "chars": 1250,
    "preview": "{\n  \"name\": \"graphql-playground-middleware-hapi\",\n  \"version\": \"1.6.19\",\n  \"homepage\": \"https://github.com/graphcool/gra"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/src/index.ts",
    "chars": 860,
    "preview": "import { Server, Plugin } from '@hapi/hapi'\nimport {\n  MiddlewareOptions,\n  RenderPageOptions,\n  renderPlaygroundPage,\n}"
  },
  {
    "path": "packages/graphql-playground-middleware-hapi/tsconfig.json",
    "chars": 408,
    "preview": "{\n  \"compilerOptions\": {\n    \"outDir\": \"dist\",\n    \"target\": \"es5\",\n    \"lib\": [\"esnext\", \"dom\"],\n    \"sourceMap\": true,"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/.gitignore",
    "chars": 226,
    "preview": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modu"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/CHANGELOG.md",
    "chars": 2616,
    "preview": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://co"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/README.md",
    "chars": 1408,
    "preview": "# graphql-playground-middleware-koa\n\n> Koa middleware to expose an endpoint for the GraphQL Playground IDE\n> **SECURITY "
  },
  {
    "path": "packages/graphql-playground-middleware-koa/examples/basic/.graphqlconfig.yml",
    "chars": 231,
    "preview": "schemaPath: schema.graphql\nextensions:\n  endpoints:\n    default:\n      url: 'https://airbnb.now.sh'\n      subscription: "
  },
  {
    "path": "packages/graphql-playground-middleware-koa/examples/basic/README.md",
    "chars": 70,
    "preview": "# GraphQL Playground Koa.js Example\n\n```sh\n$ yarn\n$ node index.js\n```\n"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/examples/basic/index.js",
    "chars": 1005,
    "preview": "const gql = require('graphql-tag')\nconst koa = require('koa')\nconst koaRouter = require('koa-router')\nconst koaBody = re"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/examples/basic/package.json",
    "chars": 535,
    "preview": "{\n  \"name\": \"koa\",\n  \"version\": \"1.2.1-beta.1\",\n  \"description\": \"\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"start\": \""
  },
  {
    "path": "packages/graphql-playground-middleware-koa/package.json",
    "chars": 1191,
    "preview": "{\n  \"name\": \"graphql-playground-middleware-koa\",\n  \"version\": \"1.6.21\",\n  \"homepage\": \"https://github.com/graphcool/grap"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/src/index.ts",
    "chars": 696,
    "preview": "import { Context, Next } from 'koa'\nimport {\n  MiddlewareOptions,\n  renderPlaygroundPage,\n} from 'graphql-playground-htm"
  },
  {
    "path": "packages/graphql-playground-middleware-koa/tsconfig.json",
    "chars": 408,
    "preview": "{\n  \"compilerOptions\": {\n    \"outDir\": \"dist\",\n    \"target\": \"es5\",\n    \"lib\": [\"esnext\", \"dom\"],\n    \"sourceMap\": true,"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/.gitignore",
    "chars": 226,
    "preview": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modu"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/CHANGELOG.md",
    "chars": 3260,
    "preview": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://co"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/LICENSE",
    "chars": 1066,
    "preview": "MIT License\n\nCopyright (c) 2017 Graphcool\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/README.md",
    "chars": 1358,
    "preview": "# graphql-playground-middleware-lambda\n\n> Koa middleware to expose an endpoint for the GraphQL Playground IDE\n> **SECURI"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/examples/basic/.gitignore",
    "chars": 25,
    "preview": "node_modules\n.serverless\n"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/examples/basic/README.md",
    "chars": 266,
    "preview": "# graphql playground serverless example\n\n## Deploy\n\n```\n$ sls deploy\n```\n\n## Hosted Example\n\nThis example is also hosted"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/examples/basic/handler.js",
    "chars": 966,
    "preview": "// or using require()\nconst { makeExecutableSchema } = require('graphql-tools')\nconst lambdaPlayground = require('graphq"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/examples/basic/package.json",
    "chars": 326,
    "preview": "{\n  \"name\": \"example\",\n  \"version\": \"1.0.0\",\n  \"main\": \"index.js\",\n  \"license\": \"MIT\",\n  \"dependencies\": {\n    \"apollo-s"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/examples/basic/serverless.yml",
    "chars": 375,
    "preview": "service: playground-test\n\nprovider:\n  name: aws\n  runtime: nodejs6.10\n\n\nfunctions:\n  graphql:\n    handler: handler.graph"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/package.json",
    "chars": 1217,
    "preview": "{\n  \"name\": \"graphql-playground-middleware-lambda\",\n  \"version\": \"1.7.23\",\n  \"homepage\": \"https://github.com/graphcool/g"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/src/index.ts",
    "chars": 486,
    "preview": "import * as lambda from 'aws-lambda'\nimport {\n  MiddlewareOptions,\n  renderPlaygroundPage,\n} from 'graphql-playground-ht"
  },
  {
    "path": "packages/graphql-playground-middleware-lambda/tsconfig.json",
    "chars": 408,
    "preview": "{\n  \"compilerOptions\": {\n    \"outDir\": \"dist\",\n    \"target\": \"es5\",\n    \"lib\": [\"esnext\", \"dom\"],\n    \"sourceMap\": true,"
  },
  {
    "path": "packages/graphql-playground-react/.babelrc",
    "chars": 180,
    "preview": "{\n  \"presets\": [\n    \"@babel/preset-env\",\n    \"@babel/preset-react\"\n  ],\n  \"plugins\": [\n    \"@babel/plugin-proposal-obje"
  },
  {
    "path": "packages/graphql-playground-react/.gitignore",
    "chars": 301,
    "preview": "# See http://help.github.com/ignore-files/ for more about ignoring files.\n\n# dependencies\nnode_modules\nexample/node_modu"
  },
  {
    "path": "packages/graphql-playground-react/CHANGELOG.md",
    "chars": 12810,
    "preview": "# Change Log\n\nAll notable changes to this project will be documented in this file.\nSee [Conventional Commits](https://co"
  },
  {
    "path": "packages/graphql-playground-react/LICENSE",
    "chars": 1077,
    "preview": "\nMIT License\n\nCopyright (c) 2017 Contributors et.al.\n\nPermission is hereby granted, free of charge, to any person obtain"
  },
  {
    "path": "packages/graphql-playground-react/README.md",
    "chars": 6206,
    "preview": "<p align=\"center\"><img src=\"https://imgur.com/5fzMbyV.png\" width=\"269\"></p>\n\nGraphQL IDE for better development workflow"
  },
  {
    "path": "packages/graphql-playground-react/config/env.js",
    "chars": 3370,
    "preview": "'use strict';\n\nconst fs = require('fs');\nconst path = require('path');\nconst paths = require('./paths');\n\n// Make sure t"
  },
  {
    "path": "packages/graphql-playground-react/config/jest/cssTransform.js",
    "chars": 323,
    "preview": "// This is a custom Jest transformer turning style imports into empty objects.\n// http://facebook.github.io/jest/docs/tu"
  },
  {
    "path": "packages/graphql-playground-react/config/jest/fileTransform.js",
    "chars": 301,
    "preview": "const path = require('path');\n\n// This is a custom Jest transformer turning file imports into filenames.\n// http://faceb"
  },
  {
    "path": "packages/graphql-playground-react/config/jest/typescriptTransform.js",
    "chars": 396,
    "preview": "// Copyright 2004-present Facebook. All Rights Reserved.\n\nconst tsc = require('typescript');\n\nmodule.exports = {\n  proce"
  },
  {
    "path": "packages/graphql-playground-react/config/paths.js",
    "chars": 2120,
    "preview": "'use strict'\n\nconst path = require('path')\nconst fs = require('fs')\nconst url = require('url')\n\n// Make sure any symlink"
  },
  {
    "path": "packages/graphql-playground-react/config/polyfills.js",
    "chars": 613,
    "preview": "if (typeof Promise === 'undefined') {\n  // Rejection tracking prevents a common issue where React gets into an\n  // inco"
  },
  {
    "path": "packages/graphql-playground-react/config/webpack.config.dev.js",
    "chars": 11153,
    "preview": "'use strict'\n\nconst path = require('path')\nconst webpack = require('webpack')\nconst HtmlWebpackPlugin = require('html-we"
  },
  {
    "path": "packages/graphql-playground-react/config/webpack.config.prod.js",
    "chars": 12795,
    "preview": "'use strict'\n\nconst path = require('path')\nconst webpack = require('webpack')\nconst HtmlWebpackPlugin = require('html-we"
  },
  {
    "path": "packages/graphql-playground-react/config/webpackDevServer.config.js",
    "chars": 5237,
    "preview": "'use strict';\n\nconst errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware');\nconst noopServiceWorker"
  },
  {
    "path": "packages/graphql-playground-react/jest.config.js",
    "chars": 883,
    "preview": "module.exports = {\n  roots: ['<rootDir>/src'],\n  transform: {\n    '^.+\\\\.css$': '<rootDir>/config/jest/cssTransform.js',"
  },
  {
    "path": "packages/graphql-playground-react/package.json",
    "chars": 6654,
    "preview": "{\n  \"name\": \"graphql-playground-react\",\n  \"version\": \"1.7.27\",\n  \"main\": \"./lib/lib.js\",\n  \"typings\": \"./lib/lib.d.ts\",\n"
  },
  {
    "path": "packages/graphql-playground-react/public/_headers",
    "chars": 71,
    "preview": "/*.graphql\n  Content-Type: text/plain\n  Access-Control-Allow-Origin: *\n"
  },
  {
    "path": "packages/graphql-playground-react/public/_redirects",
    "chars": 47,
    "preview": "# general fallback\n/*        /index.html   200\n"
  },
  {
    "path": "packages/graphql-playground-react/public/affiliates.graphql",
    "chars": 329,
    "preview": "type Affiliate @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  company: String!\n  author: U"
  },
  {
    "path": "packages/graphql-playground-react/public/auth.graphql",
    "chars": 102,
    "preview": "type User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/blogging.graphql",
    "chars": 556,
    "preview": "enum UserRole { Standard, Admin }\n\ntype User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n"
  },
  {
    "path": "packages/graphql-playground-react/public/chat.graphql",
    "chars": 337,
    "preview": "type Person @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String! @isUnique\n  messa"
  },
  {
    "path": "packages/graphql-playground-react/public/conferences.graphql",
    "chars": 359,
    "preview": "type Conference @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  city: Strin"
  },
  {
    "path": "packages/graphql-playground-react/public/empty.graphql",
    "chars": 125,
    "preview": "type User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n}\n\n# type Tweet {\n#   text: String!"
  },
  {
    "path": "packages/graphql-playground-react/public/freecom.graphql",
    "chars": 1284,
    "preview": "type File @model {\n  contentType: String!\n  createdAt: DateTime!\n  id: ID! @isUnique\n  name: String!\n  secret: String!\n "
  },
  {
    "path": "packages/graphql-playground-react/public/hn-relay-full.graphql",
    "chars": 19577,
    "preview": "input AUTH_PROVIDER_EMAIL {\n  email: String!\n  password: String!\n}\n\ninput AddToUsersLinksLinkInput {\n  postedByUserId: I"
  },
  {
    "path": "packages/graphql-playground-react/public/hn-relay.graphql",
    "chars": 594,
    "preview": "type User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  links: [Link!] @r"
  },
  {
    "path": "packages/graphql-playground-react/public/hn-starter.graphql",
    "chars": 125,
    "preview": "type Link @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  url: String!\n  description: Strin"
  },
  {
    "path": "packages/graphql-playground-react/public/hn.graphql",
    "chars": 593,
    "preview": "type User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  links: [Link!] @r"
  },
  {
    "path": "packages/graphql-playground-react/public/index.html",
    "chars": 18787,
    "preview": "<!DOCTYPE html>\n<html>\n\n<head>\n  <meta charset=utf-8 />\n  <meta name=\"viewport\" content=\"user-scalable=no, initial-scale"
  },
  {
    "path": "packages/graphql-playground-react/public/insta-auth0.graphql",
    "chars": 288,
    "preview": "type Post @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  description: String!\n  imageUrl: "
  },
  {
    "path": "packages/graphql-playground-react/public/insta-email.graphql",
    "chars": 281,
    "preview": "type Post @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  description: String!\n  imageUrl: "
  },
  {
    "path": "packages/graphql-playground-react/public/insta-expo-auth.graphql",
    "chars": 659,
    "preview": "type User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  posts: [Post!]!  @relation(name: "
  },
  {
    "path": "packages/graphql-playground-react/public/insta-files.graphql",
    "chars": 283,
    "preview": "type Post @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  description: String!\n  image: Fil"
  },
  {
    "path": "packages/graphql-playground-react/public/instagram-full.graphql",
    "chars": 11566,
    "preview": "# The `BigDecimal` scalar type represents signed fractional values with arbitrary precision.\nscalar BigDecimal\n\n# The `B"
  },
  {
    "path": "packages/graphql-playground-react/public/instagram.graphql",
    "chars": 130,
    "preview": "type Post @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  description: String!\n  imageUrl: "
  },
  {
    "path": "packages/graphql-playground-react/public/movies-import.graphql",
    "chars": 161,
    "preview": "type Movie @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  oldid: String\n  description: Str"
  },
  {
    "path": "packages/graphql-playground-react/public/pokedex.graphql",
    "chars": 105,
    "preview": "type Pokemon @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/simple-pokedex.graphql",
    "chars": 121,
    "preview": "type Pokemon @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  url: String!\n}"
  },
  {
    "path": "packages/graphql-playground-react/public/todo.graphql",
    "chars": 78,
    "preview": "type Todo @model {\n  id: ID! @isUnique\n  text: String!\n  complete: Boolean!\n}\n"
  },
  {
    "path": "packages/graphql-playground-react/public/twitter.graphql",
    "chars": 350,
    "preview": "type User @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  username: String!\n  followers: [U"
  },
  {
    "path": "packages/graphql-playground-react/public/welcome-rp.graphql",
    "chars": 124,
    "preview": "type Customer @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  email: String"
  },
  {
    "path": "packages/graphql-playground-react/public/welcome.graphql",
    "chars": 123,
    "preview": "type Customer @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  email: String"
  },
  {
    "path": "packages/graphql-playground-react/public/worldchat.graphql",
    "chars": 594,
    "preview": "type Traveller @model {\n  id: ID! @isUnique\n  createdAt: DateTime!\n  updatedAt: DateTime!\n  name: String!\n  location: Lo"
  },
  {
    "path": "packages/graphql-playground-react/release.sh",
    "chars": 311,
    "preview": "#!/bin/bash\n\nset -e\n\n#npm publish\n\ncurl -X POST \\\n  http://purge.jsdelivr.net/ \\\n  -H 'cache-control: no-cache' \\\n  -H '"
  },
  {
    "path": "packages/graphql-playground-react/scripts/build.js",
    "chars": 8788,
    "preview": "// Do this as the first thing so that any code reading it knows the right env.\nprocess.env.NODE_ENV = 'production';\n\n// "
  },
  {
    "path": "packages/graphql-playground-react/scripts/start.js",
    "chars": 3204,
    "preview": "'use strict';\n\n// Do this as the first thing so that any code reading it knows the right env.\nprocess.env.BABEL_ENV = 'd"
  },
  {
    "path": "packages/graphql-playground-react/scripts/test.js",
    "chars": 994,
    "preview": "process.env.NODE_ENV = 'test';\nprocess.env.PUBLIC_URL = '';\n\n// Load environment variables from .env file. Suppress warn"
  },
  {
    "path": "packages/graphql-playground-react/src/__snapshots__/index.test.tsx.snap",
    "chars": 27206,
    "preview": "// Jest Snapshot v1, https://goo.gl/fbAQLP\n\nexports[`test MiddleWareApp passed default headers 1`] = `\n<div>\n  <div\n    "
  },
  {
    "path": "packages/graphql-playground-react/src/components/Button.tsx",
    "chars": 1558,
    "preview": "import * as React from 'react'\nimport { styled } from '../styled'\nimport { FullArrowRightIcon } from './Icons'\n\nexport i"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Copy.tsx",
    "chars": 1477,
    "preview": "import * as React from 'react'\nimport { styled } from '../styled'\nimport * as CopyToClipboard from 'react-copy-to-clipbo"
  },
  {
    "path": "packages/graphql-playground-react/src/components/EndpointPopup.tsx",
    "chars": 4683,
    "preview": "import * as React from 'react'\nimport * as fetch from 'isomorphic-fetch'\nimport Popup from './Popup'\nimport { throttle }"
  },
  {
    "path": "packages/graphql-playground-react/src/components/FileEditor.tsx",
    "chars": 1460,
    "preview": "import * as React from 'react'\nimport { styled } from '../styled'\nimport { QueryEditor } from './Playground/QueryEditor'"
  },
  {
    "path": "packages/graphql-playground-react/src/components/GraphQLBinApp.tsx",
    "chars": 4338,
    "preview": "import * as React from 'react'\nimport { Provider, connect } from 'react-redux'\nimport createStore from '../state/createS"
  },
  {
    "path": "packages/graphql-playground-react/src/components/HistoryPopup/HistoryChooser.tsx",
    "chars": 1921,
    "preview": "import * as React from 'react'\nimport { HistoryFilter } from '../../types'\nimport { styled, withTheme, ThemeInterface } "
  },
  {
    "path": "packages/graphql-playground-react/src/components/HistoryPopup/HistoryHeader.tsx",
    "chars": 835,
    "preview": "import * as React from 'react'\nimport HistoryChooser from './HistoryChooser'\nimport { HistoryFilter } from '../../types'"
  },
  {
    "path": "packages/graphql-playground-react/src/components/HistoryPopup/HistoryItems.tsx",
    "chars": 3615,
    "preview": "import * as React from 'react'\nimport { Session } from '../../state/sessions/reducers'\nimport { OrderedMap } from 'immut"
  },
  {
    "path": "packages/graphql-playground-react/src/components/HistoryPopup.tsx",
    "chars": 6423,
    "preview": "import * as React from 'react'\nimport * as Modal from 'react-modal'\nimport HistoryHeader from './HistoryPopup/HistoryHea"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Icons/index.tsx",
    "chars": 6523,
    "preview": "import * as React from 'react'\n\ninterface IProps {\n  title?: string\n  color?: string\n  width?: number\n  height?: number\n"
  },
  {
    "path": "packages/graphql-playground-react/src/components/MiddlewareApp.tsx",
    "chars": 849,
    "preview": "import * as React from 'react'\nimport { Provider } from 'react-redux'\nimport createStore from '../state/createStore'\nimp"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Modal.tsx",
    "chars": 570,
    "preview": "import * as React from 'react'\nimport * as Modal from 'react-modal'\nimport { modalStyle } from '../constants'\n\nexport in"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/ConfigEditor.tsx",
    "chars": 5141,
    "preview": "import * as React from 'react'\nimport EditorWrapper from './EditorWrapper'\nimport { styled } from '../../styled'\n\nexport"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/Argument.tsx",
    "chars": 789,
    "preview": "import * as React from 'react'\nimport { astFromValue, print } from 'graphql'\nimport TypeLink from './TypeLink'\n\nexport i"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/ArgumentInline.tsx",
    "chars": 1158,
    "preview": "import * as React from 'react'\nimport { astFromValue, print, GraphQLList, GraphQLNonNull } from 'graphql'\nimport { style"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/ColumnDoc.tsx",
    "chars": 792,
    "preview": "import * as React from 'react'\nimport { columnWidth } from '../../../constants'\nimport { styled } from '../../../styled'"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/DocTypeSchema.tsx",
    "chars": 2706,
    "preview": "import { GraphQLInterfaceType } from 'graphql'\nimport * as React from 'react'\nimport TypeLink from './TypeLink'\nimport {"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/DocsStyles.tsx",
    "chars": 362,
    "preview": "import * as React from 'react'\nimport { styled } from '../../../styled'\n\nconst Title = styled.div`\n  color: rgba(0, 0, 0"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/DocsTypes/DocType.tsx",
    "chars": 148,
    "preview": "import { styled } from '../../../../styled'\n\nexport const DocType = styled.div`\n  padding: 20px 16px 0 16px;\n  overflow:"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/DocsTypes/EnumTypeSchema.tsx",
    "chars": 1874,
    "preview": "import * as React from 'react'\nimport { styled } from '../../../../styled'\nimport { DocType } from './DocType'\n\nexport i"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/DocsTypes/ScalarType.tsx",
    "chars": 402,
    "preview": "import * as React from 'react'\nimport { DocType } from './DocType'\n\nexport interface ScalarTypeSchemaProps {\n  type: any"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/DocsTypes/UnionTypeSchema.tsx",
    "chars": 835,
    "preview": "import TypeLink from '../TypeLink'\nimport * as React from 'react'\nimport { DocType } from './DocType'\n\nexport interface "
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/ErrorContainer.tsx",
    "chars": 286,
    "preview": "import { styled } from '../../../styled'\nexport const ErrorContainer = styled.div`\n  font-weight: bold;\n  left: 0;\n  let"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/FieldDoc.tsx",
    "chars": 5312,
    "preview": "import * as React from 'react'\nimport Argument from './Argument'\nimport {\n  GraphQLInterfaceType,\n  GraphQLEnumType,\n  G"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/GraphDocs.tsx",
    "chars": 7637,
    "preview": "import * as React from 'react'\nimport { bindActionCreators } from 'redux'\nimport { connect } from 'react-redux'\nimport *"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/GraphDocsRoot.tsx",
    "chars": 2474,
    "preview": "import * as React from 'react'\nimport TypeLink from './TypeLink'\nimport { serializeRoot } from '../util/stack'\nimport { "
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/RootColumn.tsx",
    "chars": 1083,
    "preview": "import * as React from 'react'\nimport ColumnDoc from './ColumnDoc'\nimport SearchResults from './SearchResults'\nimport Gr"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/SchemaDoc.tsx",
    "chars": 2086,
    "preview": "/**\n *  Copyright (c) Facebook, Inc.\n *  All rights reserved.\n *\n *  This source code is licensed under the license foun"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/SearchBox.tsx",
    "chars": 1985,
    "preview": "import * as React from 'react'\nimport debounce from 'graphiql/dist/utility/debounce'\nimport { Search } from '../../Icons"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/SearchResults.tsx",
    "chars": 3649,
    "preview": "import * as React from 'react'\nimport { styled } from '../../../styled'\nimport TypeLink from './TypeLink'\n\nexport interf"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/DocExplorer/TypeLink.tsx",
    "chars": 6367,
    "preview": "import * as React from 'react'\nimport { bindActionCreators } from 'redux'\nimport { connect } from 'react-redux'\nimport {"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/EditorWrapper.tsx",
    "chars": 22301,
    "preview": "import * as React from 'react'\nimport { styled, createGlobalStyle } from '../../styled'\n\nconst EditorWrapper = styled.di"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/ExecuteButton.tsx",
    "chars": 6779,
    "preview": "/**\n *  Copyright (c) Facebook, Inc.\n *  All rights reserved.\n *\n *  This source code is licensed under the license foun"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/ExecuteButtonOperation.tsx",
    "chars": 942,
    "preview": "import * as React from 'react'\n\nexport interface Props {\n  operation: any\n  onMouseOver: (operation: any) => void\n  onMo"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/ExplorerTabs/SideTab.tsx",
    "chars": 1396,
    "preview": "import * as React from 'react'\nimport { styled } from '../../../styled'\n\nexport interface Props {\n  label: string\n  acti"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/ExplorerTabs/SideTabs.tsx",
    "chars": 9264,
    "preview": "import * as React from 'react'\nimport { bindActionCreators } from 'redux'\nimport { connect } from 'react-redux'\nimport *"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/GraphQLEditor.tsx",
    "chars": 22913,
    "preview": "import * as React from 'react'\nimport * as ReactDOM from 'react-dom'\nimport { isNamedType, GraphQLSchema } from 'graphql"
  },
  {
    "path": "packages/graphql-playground-react/src/components/Playground/QueryEditor.tsx",
    "chars": 9286,
    "preview": "/**\n *  Copyright (c) Facebook, Inc.\n *  All rights reserved.\n *\n *  This source code is licensed under the license foun"
  }
]

// ... and 116 more files (download for full content)

About this extraction

This page contains the full source code of the graphql/graphql-playground GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 316 files (869.0 KB), approximately 246.0k tokens, and a symbol index with 609 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!