├── .all-contributorsrc
├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .github
├── ISSUE_TEMPLATE.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ └── release.yml
├── .gitignore
├── .npmignore
├── .travis.yml
├── .yo-rc.json
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.md
├── README.md
├── commitlint.config.js
├── docs
├── example-output-full.png
├── example-output-mutation.png
└── example-output.png
├── package.json
├── src
├── __tests__
│ ├── __snapshots__
│ │ └── formatMessage.test.js.snap
│ ├── formatMessage.test.js
│ └── logging.test.js
├── formatMessage.js
├── index.js
└── logging.js
├── wallaby.config.js
└── yarn.lock
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "apollo-link-logger",
3 | "projectOwner": "blackxored",
4 | "files": [
5 | "README.md"
6 | ],
7 | "imageSize": 100,
8 | "commit": false,
9 | "contributors": [
10 | {
11 | "login": "blackxored",
12 | "name": "Adrian Perez",
13 | "avatar_url": "https://avatars3.githubusercontent.com/u/133308?v=4",
14 | "profile": "https://adrianperez.codes",
15 | "contributions": [
16 | "code",
17 | "doc",
18 | "infra",
19 | "test"
20 | ]
21 | },
22 | {
23 | "login": "adambom",
24 | "name": "Adam Savitzky",
25 | "avatar_url": "https://avatars3.githubusercontent.com/u/294597?s=460&v=4",
26 | "profile": "https://github.com/adambom",
27 | "contributions": [
28 | "code"
29 | ]
30 | },
31 | {
32 | "login": "gnerkus",
33 | "name": "Ifeanyi Oraelosi",
34 | "avatar_url": "https://avatars3.githubusercontent.com/u/3065138?v=4",
35 | "profile": "https://github.com/gnerkus",
36 | "contributions": [
37 | "code"
38 | ]
39 | },
40 | {
41 | "login": "romarioraffington",
42 | "name": "Romario",
43 | "avatar_url": "https://avatars0.githubusercontent.com/u/7076981?v=4",
44 | "profile": "https://github.com/romarioraffington",
45 | "contributions": [
46 | "bug",
47 | "ideas"
48 | ]
49 | },
50 | {
51 | "login": "Horoshiy",
52 | "name": "Yuriy Kornienko",
53 | "avatar_url": "https://avatars0.githubusercontent.com/u/6183943?v=4",
54 | "profile": "http://www.dinamchiki.ru",
55 | "contributions": [
56 | "code"
57 | ]
58 | },
59 | {
60 | "login": "dmt0",
61 | "name": "Dmitry Shvedov",
62 | "avatar_url": "https://avatars1.githubusercontent.com/u/2717746?v=4",
63 | "profile": "https://github.com/dmt0",
64 | "contributions": [
65 | "code"
66 | ]
67 | }
68 | ],
69 | "repoType": "github"
70 | }
71 |
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": "env",
3 | "env": {
4 | "cjs": {
5 | "plugins": [["transform-es2015-modules-commonjs", { "loose": true }]]
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | # Unix-style newlines with a newline ending every file
7 | [*]
8 | end_of_line = lf
9 | insert_final_newline = true
10 | indent_style = space
11 | indent_size = 2
12 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | coverage
3 | dist
4 | wallaby.config.js
5 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['airbnb-base', 'prettier'],
3 | parser: 'babel-eslint',
4 | plugins: ['prettier', 'jest'],
5 | env: {
6 | jest: true,
7 | },
8 | rules: {
9 | 'arrow-body-style': 0,
10 | 'arrow-parens': 0, // does not work with Flow generic types.
11 | 'global-require': 0, // used by react-native
12 | 'import/first': 0, // we sort by unit/atom
13 | 'import/no-named-as-default': 0, // we export components for testing
14 | 'import/prefer-default-export': 0, // actions can have only one action
15 | 'no-confusing-arrow': 0, // this rule is confusing
16 | 'no-duplicate-imports': 0, // handled by eslint-plugin-import
17 | 'no-underscore-dangle': 0,
18 | 'require-jsdoc': 'warn',
19 | 'valid-jsdoc': 'error',
20 | },
21 | };
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
13 |
14 | * `apollo-link-logger` version:
15 | * `node` version:
16 | * `npm` (or `yarn`) version:
17 |
18 | Relevant code or config
19 |
20 | ```javascript
21 | ```
22 |
23 | What you did:
24 |
25 | What happened:
26 |
27 |
28 |
29 | Reproduction repository:
30 |
31 |
35 |
36 | Problem description:
37 |
38 | Suggested solution:
39 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 | **What**:
20 |
21 |
22 |
23 | **Why**:
24 |
25 |
26 |
27 | **How**:
28 |
29 |
30 |
31 | **Checklist**:
32 |
33 |
34 |
35 |
36 |
37 | * [ ] Documentation
38 | * [ ] Tests
39 | * [ ] Ready to be merged
40 |
41 | * [ ] Added myself to contributors table
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 | on:
3 | push:
4 | branches:
5 | - master
6 | jobs:
7 | release:
8 | name: Release
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Checkout
12 | uses: actions/checkout@v3
13 | with:
14 | fetch-depth: 0
15 | - name: Setup Node.js
16 | uses: actions/setup-node@v3
17 | with:
18 | node-version: "lts/*"
19 | - name: Install dependencies
20 | run: yarn
21 | - name: Release
22 | env:
23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
25 | run: npx semantic-release
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### Node ###
2 |
3 | # Logs
4 | logs
5 | npm-debug.log*
6 | yarn-debug.log*
7 | yarn-error.log*
8 |
9 | # Optional npm cache directory
10 | .npm
11 |
12 | # Dependency directories
13 | /node_modules
14 | /jspm_packages
15 | /bower_components
16 |
17 | # Yarn Integrity file
18 | .yarn-integrity
19 |
20 | # Optional eslint cache
21 | .eslintcache
22 |
23 | # dotenv environment variables file(s)
24 | .env
25 | .env.*
26 |
27 | #Build generated
28 | dist/
29 | build/
30 | es/
31 | lib/
32 | coverage/
33 |
34 |
35 | ### SublimeText ###
36 | # cache files for sublime text
37 | *.tmlanguage.cache
38 | *.tmPreferences.cache
39 | *.stTheme.cache
40 |
41 | # workspace files are user-specific
42 | *.sublime-workspace
43 |
44 | # project files should be checked into the repository, unless a significant
45 | # proportion of contributors will probably not be using SublimeText
46 | # *.sublime-project
47 |
48 |
49 | ### VisualStudioCode ###
50 | .vscode/*
51 | !.vscode/settings.json
52 | !.vscode/tasks.json
53 | !.vscode/launch.json
54 | !.vscode/extensions.json
55 |
56 | ### WebStorm/IntelliJ ###
57 | /.idea
58 | modules.xml
59 | *.ipr
60 |
61 |
62 | ### System Files ###
63 | .DS_Store
64 |
65 | # Windows thumbnail cache files
66 | Thumbs.db
67 | ehthumbs.db
68 | ehthumbs_vista.db
69 |
70 | # Folder config file
71 | Desktop.ini
72 |
73 | # Recycle Bin used on file shares
74 | $RECYCLE.BIN/
75 |
76 | # Thumbnails
77 | ._*
78 |
79 | # Files that might appear in the root of a volume
80 | .DocumentRevisions-V100
81 | .fseventsd
82 | .Spotlight-V100
83 | .TemporaryItems
84 | .Trashes
85 | .VolumeIcon.icns
86 | ### Node ###
87 |
88 | # Logs
89 | logs
90 | npm-debug.log*
91 | yarn-debug.log*
92 | yarn-error.log*
93 |
94 | # Optional npm cache directory
95 | .npm
96 |
97 | # Dependency directories
98 | /node_modules
99 | /jspm_packages
100 | /bower_components
101 |
102 | # Yarn Integrity file
103 | .yarn-integrity
104 |
105 | # Optional eslint cache
106 | .eslintcache
107 |
108 | # dotenv environment variables file(s)
109 | .env
110 | .env.*
111 |
112 | #Build generated
113 | dist/
114 | build/
115 |
116 |
117 | ### SublimeText ###
118 | # cache files for sublime text
119 | *.tmlanguage.cache
120 | *.tmPreferences.cache
121 | *.stTheme.cache
122 |
123 | # workspace files are user-specific
124 | *.sublime-workspace
125 |
126 | # project files should be checked into the repository, unless a significant
127 | # proportion of contributors will probably not be using SublimeText
128 | # *.sublime-project
129 |
130 |
131 | ### VisualStudioCode ###
132 | .vscode/*
133 | !.vscode/settings.json
134 | !.vscode/tasks.json
135 | !.vscode/launch.json
136 | !.vscode/extensions.json
137 |
138 | ### WebStorm/IntelliJ ###
139 | /.idea
140 | modules.xml
141 | *.ipr
142 |
143 |
144 | ### System Files ###
145 | .DS_Store
146 |
147 | # Windows thumbnail cache files
148 | Thumbs.db
149 | ehthumbs.db
150 | ehthumbs_vista.db
151 |
152 | # Folder config file
153 | Desktop.ini
154 |
155 | # Recycle Bin used on file shares
156 | $RECYCLE.BIN/
157 |
158 | # Thumbnails
159 | ._*
160 |
161 | # Files that might appear in the root of a volume
162 | .DocumentRevisions-V100
163 | .fseventsd
164 | .Spotlight-V100
165 | .TemporaryItems
166 | .Trashes
167 | .VolumeIcon.icns
168 | .com.apple.timemachine.donotpresent
169 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | ./**/__tests__/*.test.js
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | cache:
3 | directories:
4 | - ~/.npm
5 | notifications:
6 | email: false
7 | node_js:
8 | - '10'
9 | - '11'
10 | - '12'
11 | before_install: yarn global add greenkeeper-lockfile@1
12 | before_script: greenkeeper-lockfile-update
13 | after_script: greenkeeper-lockfile-upload
14 | install: yarn install --ignore-engines
15 | after_success:
16 | - npm run travis-deploy-once "npm run semantic-release"
17 | branches:
18 | except:
19 | - /^v\d+\.\d+\.\d+$/
20 | env:
21 | - GK_LOCK_YARN_OPTS: "--ignore-engines"
22 |
--------------------------------------------------------------------------------
/.yo-rc.json:
--------------------------------------------------------------------------------
1 | {
2 | "generator-bxd-oss": {
3 | "promptValues": {
4 | "username": "blackxored",
5 | "teamEmail": "adrian@adrianperez.org"
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, gender identity and expression, level of
9 | experience, nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or reject
41 | comments, commits, code, wiki edits, issues, and other contributions that are
42 | not aligned to this Code of Conduct, or to ban temporarily or permanently any
43 | contributor for other behaviors that they deem inappropriate, threatening,
44 | offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team leader at [`adrian@adrianperez.org`]. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an
62 | incident. Further details of specific enforcement policies may be posted
63 | separately.
64 |
65 | Project maintainers who do not follow or enforce the Code of Conduct in good
66 | faith may face temporary or permanent repercussions as determined by other
67 | members of the project's leadership.
68 |
69 | ## Attribution
70 |
71 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
72 | version 1.4, available at
73 | https://www.contributor-covenant.org/version/1/4/code-of-conduct/
74 |
75 | [homepage]: https://www.contributor-covenant.org
76 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Thanks for being willing to contribute!
4 |
5 | **Working on your first Pull Request?** You can learn how from this _free_
6 | series [How to Contribute to an Open Source Project on GitHub][egghead]
7 |
8 | ## Project setup
9 |
10 | 1. Fork and clone the repo
11 | 2. `$ yarn` to install dependencies
12 | 3. `$ yarn test` to validate you've got it working
13 | 4. Create a branch for your PR
14 |
15 | > Tip: Keep your `master` branch pointing at the original repository and make
16 | > pull requests from branches on your fork. To do this, run:
17 | >
18 | > ```
19 | > git remote add upstream https://github.com/blackxored/apollo-link-logger.git
20 | > git fetch upstream
21 | > git branch --set-upstream-to=upstream/master master
22 | > ```
23 | >
24 | > This will add the original repository as a "remote" called "upstream," Then
25 | > fetch the git information from that remote, then set your local `master`
26 | > branch to use the upstream master branch whenever you run `git pull`. Then you
27 | > can make all of your pull request branches based on this `master` branch.
28 | > Whenever you want to update your version of `master`, do a regular `git pull`.
29 |
30 | ## Add yourself as a contributor
31 |
32 | This project follows the [all contributors][all-contributors] specification. To
33 | add yourself to the table of contributors on the README.md, please use the
34 | automated script as part of your PR:
35 |
36 | ```console
37 | yarn run contributors:add
38 | ```
39 |
40 | Follow the prompt and commit `.all-contributorsrc` and `README.md` in the PR. If
41 | you've already added yourself to the list and are making a new type of
42 | contribution, you can run it again and select the added contribution type.
43 |
44 | ## Committing and Pushing changes
45 |
46 | This project uses [`semantic-release`][semantic-release] to do automatic
47 | releases and generate a changelog based on the commit history. So we follow [a
48 | convention][convention] for commit messages. You don't have to follow this
49 | convention if you don't like to, although we've provided hooks to make it easier
50 | for you to adhere to them if you so choose. Just know that when we merge your
51 | commit, we'll probably use "Squash and Merge" so we can change the commit
52 | message :)
53 |
54 | Please make sure to run the tests before you commit your changes. You can run
55 | `npm test -- -u` which will update any snapshots that need updating. Make sure
56 | to include those changes (if they exist) in your commit.
57 |
58 | ## Help needed
59 |
60 | Please checkout the [the open issues][issues]
61 |
62 | Also, please watch the repo and respond to questions/bug reports/feature
63 | requests! Thanks!
64 |
65 | [egghead]: https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github
66 | [semantic-release]: https://npmjs.com/package/semantic-release
67 | [convention]: https://github.com/conventional-changelog/conventional-changelog-angular/blob/ed32559941719a130bb0327f886d6a32a8cbc2ba/convention.md
68 | [all-contributors]: https://github.com/kentcdodds/all-contributors
69 | [issues]: https://github.com/blackxored/apollo-link-logger/issues
70 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 | Copyright (c) 2017-present Adrian Perez
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining a copy
5 | of this software and associated documentation files (the "Software"), to deal
6 | in the Software without restriction, including without limitation the rights
7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the Software is
9 | furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included in all
12 | copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 | SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # apollo-link-logger
2 |
3 | > A logger for Apollo Link that resembles redux-logger
4 |
5 | [![Semantically Released][semantic-release-badge]][semantic-release]
6 | [![Build Status][build-badge]][build]
7 | [![Code Coverage][coverage-badge]][coverage]
8 | [![version][version-badge]][package]
9 | [![downloads][downloads-badge]][npmtrends]
10 | [![Styled with Prettier][prettier-badge]][prettier]
11 | [![AirBnB style guide][airbnb-style-badge]][airbnb-style]
12 |
13 | [![MIT License][license-badge]][LICENSE]
14 | [](#contributors)
15 | [![PRs Welcome][prs-badge]][prs]
16 | [![Commitizen friendly][commitizen-badge]][commitizen]
17 | [![Code of Conduct][coc-badge]][coc]
18 |
19 | [![Watch on GitHub][github-watch-badge]][github-watch]
20 | [![Star on GitHub][github-star-badge]][github-star]
21 | [![Tweet][twitter-badge]][twitter]
22 |
23 | Logger for Apollo Link that uses a similar format to redux-logger. Includes performance information.
24 |
25 | ## Installing / Getting Started
26 |
27 | These instructions will get you a copy of the project up and running on your
28 | local machine for development and testing purposes.
29 |
30 | A quick introduction of the minimal setup you need to get a hello world up & running.
31 |
32 | ```shell
33 | npm install apollo-link-logger
34 | ```
35 |
36 | ### Prerequisites
37 |
38 | * Apollo Link.
39 |
40 | ### Usage
41 |
42 | ```javascript
43 | import apolloLogger from 'apollo-link-logger';
44 |
45 | // ...
46 | ApolloLink.from([
47 | apolloLogger,
48 | // ...
49 | ]);
50 | ```
51 |
52 | ## Screenshots
53 |
54 | ### Query (expanded):
55 |
56 | 
57 |
58 | ### Mutation (expanded):
59 |
60 | 
61 |
62 | ### Within other logging statements:
63 |
64 | 
65 |
66 | ## Usage with React Native and other restricted environments
67 |
68 | We include a polyfilled version of `console.groupCollapsed` and `console.groupEnd` that
69 | invokes `console.log` with slightly different prefix to separate output.
70 |
71 | ## Developing
72 |
73 | ### Setting up Dev
74 |
75 | Here's a brief intro about what a developer must do in order to start
76 | developing the project further:
77 |
78 | ```shell
79 | git clone https://github.com/blackxored/apollo-link-logger
80 | cd apollo-link-logger
81 | yarn
82 | ```
83 |
84 | ## Versioning
85 |
86 | We use [SemVer][semver] for versioning. In addition, it's automatic via
87 | [semantic-release][semantic-release], and our [commit convention][commit-convention].
88 |
89 | For the versions available, see the [Releases][releases] on this repository.
90 |
91 | ## Style guide
92 |
93 | We base our code style on [AirBnB's style guide][airbnb-style] and we check with
94 | [ESLint][eslint] and automatically format our code with [Prettier][prettier].
95 |
96 | ## License
97 |
98 | This project is licensed under the MIT License - see the
99 | [license] file for details.
100 |
101 | ## Contributing
102 |
103 | If you're interested in contributing to this project in any form, please read
104 | our [Contribution Guidelines][contributing].
105 |
106 | ### Code of Conduct
107 |
108 | We've adopted a Code of Conduct that we expect project participants to adhere to.
109 | Please read the [full text][coc] so that you can understand what actions
110 | will and will not be tolerated.
111 |
112 | ### Contributors
113 |
114 | Thanks goes to these people ([emoji key][emojis]):
115 |
116 |
117 |
118 | | [
Adrian Perez](https://adrianperez.codes)
[💻](https://github.com/blackxored/apollo-link-logger/commits?author=blackxored "Code") [📖](https://github.com/blackxored/apollo-link-logger/commits?author=blackxored "Documentation") [🚇](#infra-blackxored "Infrastructure (Hosting, Build-Tools, etc)") [⚠️](https://github.com/blackxored/apollo-link-logger/commits?author=blackxored "Tests") | [
Adam Savitzky](https://github.com/adambom)
[💻](https://github.com/blackxored/apollo-link-logger/commits?author=adambom "Code") | [
Ifeanyi Oraelosi](https://github.com/gnerkus)
[💻](https://github.com/blackxored/apollo-link-logger/commits?author=gnerkus "Code") | [
Romario](https://github.com/romarioraffington)
[🐛](https://github.com/blackxored/apollo-link-logger/issues?q=author%3Aromarioraffington "Bug reports") [🤔](#ideas-romarioraffington "Ideas, Planning, & Feedback") | [
Yuriy Kornienko](http://www.dinamchiki.ru)
[💻](https://github.com/blackxored/apollo-link-logger/commits?author=Horoshiy "Code") | [
Dmitry Shvedov](https://github.com/dmt0)
[💻](https://github.com/blackxored/apollo-link-logger/commits?author=dmt0 "Code") |
119 | | :---: | :---: | :---: | :---: | :---: | :---: |
120 |
121 |
122 | This project follows the [all-contributors][all-contributors] specification.
123 | Contributions of any kind welcome!
124 |
125 |
126 | [npm]: https://www.npmjs.com/
127 | [node]: https://nodejs.org
128 | [build-badge]: https://img.shields.io/travis/blackxored/apollo-link-logger.svg?style=flat-square
129 | [build]: https://travis-ci.org/blackxored/apollo-link-logger
130 | [coverage-badge]: https://img.shields.io/codecov/c/github/blackxored/apollo-link-logger.svg?style=flat-square
131 | [coverage]: https://codecov.io/github/blackxored/apollo-link-logger
132 | [version-badge]: https://img.shields.io/npm/v/apollo-link-logger.svg?style=flat-square
133 | [package]: https://www.npmjs.com/package/apollo-link-logger
134 | [downloads-badge]: https://img.shields.io/npm/dm/apollo-link-logger.svg?style=flat-square
135 | [npmtrends]: http://www.npmtrends.com/apollo-link-logger
136 | [license-badge]: https://img.shields.io/npm/l/apollo-link-logger.svg?style=flat-square
137 | [license]: https://github.com/blackxored/apollo-link-logger/blob/master/LICENSE.md
138 | [semantic-release]: https://github.com/semantic-release/semantic-release
139 | [semantic-release-badge]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square
140 | [commitizen-badge]: https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=flat-square
141 | [commitizen]: http://commitizen.github.io/cz-cli/
142 | [prettier-badge]: https://img.shields.io/badge/styled_with-prettier-ff69b4.svg?style=flat-square
143 | [prettier]: https://github.com/prettier/prettier
144 | [airbnb-style-badge]: https://img.shields.io/badge/code%20style-airbnb-green.svg?style=flat-square
145 | [airbnb-style]: https://github.com/airbnb/javascript
146 | [eslint]: http://eslint.org
147 | [prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
148 | [prs]: http://makeapullrequest.com
149 | [donate-badge]: https://img.shields.io/badge/$-support-green.svg?style=flat-square
150 | [contributing]: https://github.com/blackxored/apollo-link-logger/blob/master/CONTRIBUTING.md
151 | [coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square
152 | [coc]: https://github.com/blackxored/apollo-link-logger/blob/master/CODE_OF_CONDUCT.md
153 | [github-watch-badge]: https://img.shields.io/github/watchers/blackxored/apollo-link-logger.svg?style=social
154 | [github-watch]: https://github.com/blackxored/apollo-link-logger/watchers
155 | [github-star-badge]: https://img.shields.io/github/stars/blackxored/apollo-link-logger.svg?style=social
156 | [github-star]: https://github.com/blackxored/apollo-link-logger/stargazers
157 | [twitter]: https://twitter.com/intent/tweet?text=Check%20out%20apollo-link-logger%20by%20%40blackxored%20https%3A%2F%2Fgithub.com%2Fblackxored%2Fapollo-link-logger%20%F0%9F%91%8D
158 | [twitter-badge]: https://img.shields.io/twitter/url/https/github.com/blackxored/apollo-link-logger.svg?style=social
159 | [emojis]: https://github.com/kentcdodds/all-contributors#emoji-key
160 | [all-contributors]: https://github.com/kentcdodds/all-contributors
161 | [semver]: http://semver.org/
162 | [releases]: https://github.com/blackxored/apollo-link-logger/releases
163 | [commit-convention]: https://www.npmjs.com/package/@commitlint/config-conventional
164 |
165 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['@commitlint/config-conventional'],
3 | };
4 |
--------------------------------------------------------------------------------
/docs/example-output-full.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blackxored/apollo-link-logger/933156ae67088fc24b472a4967efd9042bd5de0f/docs/example-output-full.png
--------------------------------------------------------------------------------
/docs/example-output-mutation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blackxored/apollo-link-logger/933156ae67088fc24b472a4967efd9042bd5de0f/docs/example-output-mutation.png
--------------------------------------------------------------------------------
/docs/example-output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/blackxored/apollo-link-logger/933156ae67088fc24b472a4967efd9042bd5de0f/docs/example-output.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "apollo-link-logger",
3 | "version": "0.0.0-development",
4 | "description": "Logger for Apollo Link that uses a similar format to redux-logger. Includes performance information.",
5 | "author": "Adrian Perez adrian@adrianperez.org",
6 | "license": "MIT",
7 | "module": "es/index.js",
8 | "main": "lib/index.js",
9 | "engines": {
10 | "node": ">= 10",
11 | "npm": "> 3"
12 | },
13 | "files": [
14 | "es",
15 | "dist",
16 | "lib"
17 | ],
18 | "scripts": {
19 | "start": "webpack",
20 | "commit": "commit",
21 | "precommit": "lint-staged",
22 | "commitmsg": "commitlint -e $GIT_PARAMS",
23 | "clean": "rimraf es/* src/* dist/* coverage/*",
24 | "lint": "eslint src",
25 | "add-contributor": "all-contributors add",
26 | "generate-contributors": "all-contributors generate",
27 | "build:es": "cross-env BABEL_ENV=es babel src -q -d es",
28 | "build:cjs": "cross-env BABEL_ENV=cjs babel src -q -d lib",
29 | "build": "npm run build:es && npm run build:cjs",
30 | "test": "jest",
31 | "prettier:js": "prettier --write --trailing-comma all --tab-width 2 --single-quote --print-width 80 \"src/**/*.js\" \"!**/dist/**\"",
32 | "prepare": "npm run build",
33 | "semantic-release": "semantic-release",
34 | "travis-deploy-once": "travis-deploy-once"
35 | },
36 | "lint-staged": {
37 | "*.js": [
38 | "prettier --write --trailing-comma all --tab-width 2 --single-quote --print-width 80",
39 | "git add",
40 | "jest --bail --findRelatedTests"
41 | ]
42 | },
43 | "config": {
44 | "commitzen": {
45 | "path": "@commitlint/prompt"
46 | }
47 | },
48 | "jest": {
49 | "testMatch": [
50 | "/src/**/*.test.js"
51 | ],
52 | "collectCoverageFrom": [
53 | "src/**/*.js",
54 | "!**/node_modules/**",
55 | "!**/vendor/**"
56 | ],
57 | "testURL": "http://localhost"
58 | },
59 | "quokka": {
60 | "babel": true
61 | },
62 | "devDependencies": {
63 | "@commitlint/cli": "^6.1.3",
64 | "@commitlint/config-conventional": "^7.0.0",
65 | "all-contributors-cli": "^5.3.0",
66 | "babel-cli": "^6.0.0",
67 | "babel-core": "^6.0.0",
68 | "babel-eslint": "^8.2.3",
69 | "babel-jest": "23.0.1",
70 | "babel-preset-env": "^1.6.0",
71 | "commitizen": "^2.9.6",
72 | "cross-env": "^5.1.4",
73 | "eslint": "^5.0.0",
74 | "eslint-config-airbnb-base": "^13.0.0",
75 | "eslint-config-prettier": "^2.4.0",
76 | "eslint-plugin-fp": "^2.3.0",
77 | "eslint-plugin-import": "^2.7.0",
78 | "eslint-plugin-jest": "^21.0.0",
79 | "eslint-plugin-prettier": "^2.2.0",
80 | "husky": "^0.14.3",
81 | "jest": "^22.4.3",
82 | "lint-staged": "^7.0.4",
83 | "prettier": "^1.8.1",
84 | "rimraf": "~2.6.2",
85 | "semantic-release": "^15.9.3",
86 | "travis-deploy-once": "^5.0.1"
87 | },
88 | "peerDependencies": {
89 | "@apollo/client": "^3.0.0"
90 | },
91 | "repository": {
92 | "type": "git",
93 | "url": "https://github.com/blackxored/apollo-link-logger.git"
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/__tests__/__snapshots__/formatMessage.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`formatMessage does not include performance information for subscriptions 1`] = `
4 | Array [
5 | "%c apollo %csubscription %cMessagesSubscription",
6 | "color: gray; font-weight: lighter",
7 | "color: red;",
8 | "color: inherit;",
9 | ]
10 | `;
11 |
12 | exports[`formatMessage returns a list of strings suitable for console logging 1`] = `
13 | Array [
14 | "%c apollo %cquery %cFormatMessageQuery %c(in 1000 ms)",
15 | "color: gray; font-weight: lighter",
16 | "color: #03A9F4;",
17 | "color: inherit;",
18 | "color: gray; font-weight: lighter;",
19 | ]
20 | `;
21 |
22 | exports[`formatMessage returns a list of strings suitable for console logging 2`] = `
23 | Array [
24 | "%c apollo %cmutation %cFormatMessageMutation %c(in 500 ms)",
25 | "color: gray; font-weight: lighter",
26 | "color: red;",
27 | "color: inherit;",
28 | "color: gray; font-weight: lighter;",
29 | ]
30 | `;
31 |
--------------------------------------------------------------------------------
/src/__tests__/formatMessage.test.js:
--------------------------------------------------------------------------------
1 | import formatMessage from '../formatMessage';
2 |
3 | describe('formatMessage', () => {
4 | it('returns a list of strings suitable for console logging', () => {
5 | expect(
6 | formatMessage('query', { operationName: 'FormatMessageQuery' }, 1000),
7 | ).toMatchSnapshot();
8 |
9 | expect(
10 | formatMessage(
11 | 'mutation',
12 | { operationName: 'FormatMessageMutation' },
13 | 500,
14 | ),
15 | ).toMatchSnapshot();
16 | });
17 |
18 | it('does not include performance information for subscriptions', () => {
19 | expect(
20 | formatMessage(
21 | 'subscription',
22 | { operationName: 'MessagesSubscription' },
23 | 500,
24 | ),
25 | ).toMatchSnapshot();
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/src/__tests__/logging.test.js:
--------------------------------------------------------------------------------
1 | import logging from '../logging';
2 |
3 | const logSpy = jest.spyOn(global.console, 'log');
4 |
5 | describe('logging', () => {
6 | describe('console.groupCollapsed', () => {
7 | it('should not use custom `groupCollapsed` if `console.groupCollapsed` exists', () => {
8 | logging.groupCollapsed();
9 | expect(logSpy).not.toHaveBeenCalled();
10 | });
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/src/formatMessage.js:
--------------------------------------------------------------------------------
1 | const formatMessage = (operationType, operation, ellapsed) => {
2 | const headerCss = [
3 | 'color: gray; font-weight: lighter', // title
4 | `color: ${operationType === 'query' ? '#03A9F4' : 'red'};`, // operationType
5 | 'color: inherit;', // operationName
6 | ];
7 |
8 | const parts = [
9 | '%c apollo',
10 | `%c${operationType}`,
11 | `%c${operation.operationName}`,
12 | ];
13 |
14 | if (operationType !== 'subscription') {
15 | parts.push(`%c(in ${ellapsed} ms)`);
16 | headerCss.push('color: gray; font-weight: lighter;'); // time
17 | }
18 |
19 | return [parts.join(' '), ...headerCss];
20 | };
21 |
22 | export default formatMessage;
23 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable import/no-unresolved,import/extensions */
2 | import { ApolloLink } from '@apollo/client/core';
3 | import formatMessage from './formatMessage';
4 | import logging from './logging';
5 |
6 | const loggerLink = new ApolloLink((operation, forward) => {
7 | const startTime = new Date().getTime();
8 |
9 | return forward(operation).map(result => {
10 | const operationType = operation.query.definitions[0].operation;
11 | const ellapsed = new Date().getTime() - startTime;
12 |
13 | const group = formatMessage(operationType, operation, ellapsed);
14 |
15 | logging.groupCollapsed(...group);
16 |
17 | logging.log('INIT', operation);
18 | logging.log('RESULT', result);
19 |
20 | logging.groupEnd(...group);
21 | return result;
22 | });
23 | });
24 |
25 | export default loggerLink;
26 |
--------------------------------------------------------------------------------
/src/logging.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | const bindToConsole = (consoleMethod, polyfill) => {
3 | return consoleMethod ? consoleMethod.bind(console) : polyfill;
4 | };
5 |
6 | const logging = (() => {
7 | let prefix = '';
8 |
9 | const consoleLog = (...args) => {
10 | console.log(prefix, ...args);
11 | };
12 |
13 | const consoleError = (...args) => {
14 | console.error(prefix, ...args);
15 | };
16 |
17 | const consoleGroup = (...args) => {
18 | consoleLog(...args);
19 | prefix += '> ';
20 | };
21 |
22 | const consoleGroupEnd = () => {
23 | prefix = prefix.slice(0, -2);
24 | };
25 |
26 | return {
27 | log: consoleLog,
28 | error: consoleError,
29 | group: bindToConsole(console.group, consoleGroup),
30 | groupCollapsed: bindToConsole(console.groupCollapsed, consoleGroup),
31 | groupEnd: bindToConsole(console.groupEnd, consoleGroupEnd),
32 | };
33 | })();
34 |
35 | export default logging;
36 |
--------------------------------------------------------------------------------
/wallaby.config.js:
--------------------------------------------------------------------------------
1 | process.env.BABEL_ENV = 'test';
2 |
3 | const path = require('path');
4 |
5 | module.exports = function(wallaby) {
6 | return {
7 | files: [
8 | 'src/**/*.js',
9 | '**/*.json',
10 | '**/*.snap',
11 | 'package.json',
12 | '!**/__tests__/*.js',
13 | '!**/*.test.js',
14 | ],
15 | tests: ['**/__tests__/*.js', '**/*.test.js', '!**/node_modules/**'],
16 | env: {
17 | type: 'node',
18 | runner: 'node',
19 | },
20 |
21 | compilers: {
22 | '**/*.js': wallaby.compilers.babel(),
23 | },
24 |
25 | testFramework: 'jest',
26 |
27 | setup: wallaby => {
28 | wallaby.testFramework.configure(require('./package.json').jest);
29 | },
30 | };
31 | };
32 |
--------------------------------------------------------------------------------