├── .github
└── workflows
│ └── codeql-analysis.yml
├── .gitignore
├── LICENSE.md
├── README.md
├── dist
├── css
│ ├── app.abc8c15f.css
│ └── chunk-vendors.60f2038a.css
├── favicon.ico
├── index.html
└── js
│ ├── app.dc8ec42f.js
│ ├── app.dc8ec42f.js.map
│ ├── chunk-vendors.e46131c0.js
│ └── chunk-vendors.e46131c0.js.map
├── package-lock.json
├── package.json
├── src
├── api
│ ├── index.ts
│ └── routes
│ │ ├── cache.ts
│ │ ├── grants.ts
│ │ └── info.ts
├── app.ts
├── server.ts
├── shims-lowdb.d.ts
└── utils
│ ├── @types-information.ts
│ ├── api-factories.ts
│ ├── cache-db
│ ├── lowdb.ts
│ └── utils.ts
│ ├── generate-list.ts
│ ├── knex
│ ├── connection.ts
│ └── schema.ts
│ └── pg.ts
└── tsconfig.json
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ master ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ master ]
20 | schedule:
21 | - cron: '18 21 * * 3'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
37 | # Learn more:
38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
39 |
40 | steps:
41 | - name: Checkout repository
42 | uses: actions/checkout@v2
43 |
44 | # Initializes the CodeQL tools for scanning.
45 | - name: Initialize CodeQL
46 | uses: github/codeql-action/init@v1
47 | with:
48 | languages: ${{ matrix.language }}
49 | # If you wish to specify custom queries, you can do so here or in a config file.
50 | # By default, queries listed here will override any specified in a config file.
51 | # Prefix the list here with "+" to use these queries and those in the config file.
52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
53 |
54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
55 | # If this step fails, then you should remove it and run the build manually (see below)
56 | - name: Autobuild
57 | uses: github/codeql-action/autobuild@v1
58 |
59 | # ℹ️ Command-line programs to run using the OS shell.
60 | # 📚 https://git.io/JvXDl
61 |
62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
63 | # and modify them (or add more) to build your code if your project
64 | # uses a compiled language
65 |
66 | #- run: |
67 | # make bootstrap
68 | # make release
69 |
70 | - name: Perform CodeQL Analysis
71 | uses: github/codeql-action/analyze@v1
72 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .vscode/
3 | node_modules/
4 | build/
5 | tmp/
6 | temp/
7 | cache-db.json
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Yash Baheti
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PostgresHR
2 |
3 | [](https://www.npmjs.com/package/postgres-hr)
4 |
5 | Manage Postgres roles in a sane way.
6 |
7 | ## Installation
8 |
9 | ```bash
10 | npm i -g postgres-hr
11 | ```
12 |
13 | 
14 |
15 | ## Usage
16 |
17 | ```
18 | postgres-hr
19 | ```
20 |
21 | The UI will be available at http://localhost:9876
22 | To run the interface at a different port, set the `PORT` environment variable.
23 |
24 | ```
25 | PORT=1234 postgres-hr
26 | ```
27 |
28 | 1. Add a new connection.
29 | 2. Select it from top right dropdown.
30 | 3. Select the roles & schemas you want to work with.
31 | 4. Click away on the permissions on the column, table, etc under the roles.
32 |
33 | - Functions associated with a trigger will appear under that trigger.
34 | - Triggers associated with a table will appear under that table.
35 |
36 | ## Disclaimer
37 |
38 | I made this over an year ago, and have been using it internally for my hobby projects. This is not intended to be used on production databases, please proceed with caution. Use this on a local copy and then `pg_dumpall --roles`.
39 |
40 | Interface available here: https://github.com/butttons/postgres-hr-interface
41 |
42 | Tested manually with _PostgreSQL 11.9_ only.
43 |
--------------------------------------------------------------------------------
/dist/css/chunk-vendors.60f2038a.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * animate.css -https://daneden.github.io/animate.css/
3 | * Version - 3.7.2
4 | * Licensed under the MIT license - http://opensource.org/licenses/MIT
5 | *
6 | * Copyright (c) 2019 Daniel Eden
7 | */@-webkit-keyframes bounce{0%,20%,53%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);transform:translateZ(0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{0%,20%,53%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);transform:translateZ(0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}.headShake{-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-name:headShake;animation-name:headShake}@-webkit-keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes wobble{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{0%,11.1%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}@keyframes jello{0%,11.1%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}.jello{-webkit-animation-name:jello;animation-name:jello;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes heartBeat{0%{-webkit-transform:scale(1);transform:scale(1)}14%{-webkit-transform:scale(1.3);transform:scale(1.3)}28%{-webkit-transform:scale(1);transform:scale(1)}42%{-webkit-transform:scale(1.3);transform:scale(1.3)}70%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes heartBeat{0%{-webkit-transform:scale(1);transform:scale(1)}14%{-webkit-transform:scale(1.3);transform:scale(1.3)}28%{-webkit-transform:scale(1);transform:scale(1)}42%{-webkit-transform:scale(1.3);transform:scale(1.3)}70%{-webkit-transform:scale(1);transform:scale(1)}}.heartBeat{-webkit-animation-name:heartBeat;animation-name:heartBeat;-webkit-animation-duration:1.3s;animation-duration:1.3s;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}@-webkit-keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}.bounceIn{-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg);transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}to{-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{0%{-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg);transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}to{-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{0%{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{0%{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotateY(-20deg);transform:perspective(400px) rotateY(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotateY(10deg);transform:perspective(400px) rotateY(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{0%{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotateY(-20deg);transform:perspective(400px) rotateY(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotateY(10deg);transform:perspective(400px) rotateY(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}}.flipOutX{-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);transform:perspective(400px) rotateY(-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);transform:perspective(400px) rotateY(-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}}.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes lightSpeedIn{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateIn{0%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateInDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateInDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateInUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateInUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}@keyframes rotateOut{0%{-webkit-transform-origin:center;transform-origin:center;opacity:1}to{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}}@keyframes rotateOutDownLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}@keyframes rotateOutDownRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}@keyframes rotateOutUpLeft{0%{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}to{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}@keyframes rotateOutUpRight{0%{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}to{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);transform:rotate(80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate(60deg);transform:rotate(60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);transform:rotate(80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate(60deg);transform:rotate(60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes jackInTheBox{0%{opacity:0;-webkit-transform:scale(.1) rotate(30deg);transform:scale(.1) rotate(30deg);-webkit-transform-origin:center bottom;transform-origin:center bottom}50%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}70%{-webkit-transform:rotate(3deg);transform:rotate(3deg)}to{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes jackInTheBox{0%{opacity:0;-webkit-transform:scale(.1) rotate(30deg);transform:scale(.1) rotate(30deg);-webkit-transform-origin:center bottom;transform-origin:center bottom}50%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}70%{-webkit-transform:rotate(3deg);transform:rotate(3deg)}to{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}.jackInTheBox{-webkit-animation-name:jackInTheBox;animation-name:jackInTheBox}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);transform:translate3d(-100%,0,0) rotate(-120deg)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);transform:translate3d(-100%,0,0) rotate(-120deg)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate(120deg);transform:translate3d(100%,0,0) rotate(120deg)}}@keyframes rollOut{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate(120deg);transform:translate3d(100%,0,0) rotate(120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp}.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.delay-1s{-webkit-animation-delay:1s;animation-delay:1s}.animated.delay-2s{-webkit-animation-delay:2s;animation-delay:2s}.animated.delay-3s{-webkit-animation-delay:3s;animation-delay:3s}.animated.delay-4s{-webkit-animation-delay:4s;animation-delay:4s}.animated.delay-5s{-webkit-animation-delay:5s;animation-delay:5s}.animated.fast{-webkit-animation-duration:.8s;animation-duration:.8s}.animated.faster{-webkit-animation-duration:.5s;animation-duration:.5s}.animated.slow{-webkit-animation-duration:2s;animation-duration:2s}.animated.slower{-webkit-animation-duration:3s;animation-duration:3s}@media (prefers-reduced-motion:reduce),(print){.animated{-webkit-animation-duration:1ms!important;animation-duration:1ms!important;-webkit-transition-duration:1ms!important;transition-duration:1ms!important;-webkit-animation-iteration-count:1!important;animation-iteration-count:1!important}}
--------------------------------------------------------------------------------
/dist/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/butttons/postgres-hr/b675954fc82c5750db93ccdcda22106b6ee91f52/dist/favicon.ico
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 |
Postgres HR
--------------------------------------------------------------------------------
/dist/js/app.dc8ec42f.js:
--------------------------------------------------------------------------------
1 | (function(e){function t(t){for(var r,c,o=t[0],i=t[1],l=t[2],f=0,d=[];f0?n("select",{directives:[{name:"model",rawName:"v-model",value:e.selectedConnection,expression:"selectedConnection"}],staticClass:"input--full",on:{change:[function(t){var n=Array.prototype.filter.call(t.target.options,(function(e){return e.selected})).map((function(e){var t="_value"in e?e._value:e.value;return t}));e.selectedConnection=t.target.multiple?n:n[0]},e.handleConnectionChange]}},e._l(e.clientList,(function(t,r){return n("option",{key:r,domProps:{value:t[0]}},[e._v(e._s(e._f("clientName")(t[1])))])})),0):e._e(),n("button",{directives:[{name:"tooltip",rawName:"v-tooltip",value:"Add new database",expression:'"Add new database"'}],staticClass:"button__nav--icon ml-1",on:{click:function(t){return e.$emit("add-connection")}}},[n("fa-icon",{staticClass:"mr-1",attrs:{icon:"plus"}})],1),n("button",{directives:[{name:"tooltip",rawName:"v-tooltip",value:"Remove database",expression:'"Remove database"'}],staticClass:"button__nav--icon ml-1",on:{click:e.handleRemoveConnection}},[n("fa-icon",{staticClass:"mr-1",attrs:{icon:"trash"}})],1)]),n("button",{directives:[{name:"tooltip",rawName:"v-tooltip",value:"Show queries",expression:'"Show queries"'}],staticClass:"button__nav--icon",on:{click:function(t){return e.$emit("show-query-log")}}},[n("fa-icon",{attrs:{icon:"bolt"}})],1),n("z-checkbox",{staticClass:"ml-2",attrs:{label:"Ignore PG roles",selected:e.ignorePg},on:{selected:function(t){return e.toggleArray(e.ignorePg,t)}}})],1)])},p=[function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"text-lg text-white p-3 font-display"},[e._v("Postgres"),n("strong",[e._v("HR")])])}],h=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("fieldset",{staticClass:"border rounded border-gray-300 bg-gray-200 focus-within:bg-white focus-within:border-primary-400"},[n("legend",{staticClass:"text-sm text-gray-700"},[e._v(e._s(e.label)+" ")]),e._t("default")],2)},m=[],E=s["a"].extend({name:"v-fieldset",props:{label:String}}),g=E,C=n("2877"),b=Object(C["a"])(g,h,m,!1,null,null,null),v=b.exports,_=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"checkbox items-center p-2 inline-flex rounded pointer select-none cursor-pointer",class:e.wrapColors,on:{click:function(t){return e.$emit("selected",e.label)}}},[n("fa-icon",{staticClass:"mr-1",attrs:{icon:e.iconFont}}),n("div",{staticClass:"text-sm"},[e._v(e._s(e.label))])],1)},O=[],T=s["a"].extend({name:"z-checkbox",props:{label:String,selected:Array},computed:{isSelected:function(){return this.selected.includes(this.label)},wrapColors:function(){return{"bg-gray-300 text-gray-700 hover:bg-gray-400":!this.isSelected,"bg-green-300 text-green-700 hover:bg-green-400":this.isSelected}},iconFont:function(){return this.isSelected?["fas","check-circle"]:["far","circle"]}}}),y=T,N=(n("f7aa"),Object(C["a"])(y,_,O,!1,null,"eab987ae",null)),S=N.exports,w=(n("20d6"),function(e,t){if(e.includes(t)){var n=e.findIndex((function(e){return e===t}));e.splice(n,1)}else e.push(t)}),R={methods:{toggleArray:w}};(function(e){e["SET_INFO"]="SET_INFO",e["SET_GRANTS"]="SET_GRANTS",e["SET_SCHEMAS"]="SET_SCHEMAS",e["SET_ROLES"]="SET_ROLES",e["SELECT_SCHEMAS"]="SELECT_SCHEMAS",e["SELECT_ROLES"]="SELECT_ROLES",e["RESET_SELECTED"]="RESET_SELECTED",e["SET_CONFIG_IGNORE"]="SET_CONFIG_IGNORE",e["SET_CACHE_STATUS"]="SET_CACHE_STATUS",e["SET_CACHE_CONNECTION"]="SET_CACHE_CONNECTION",e["SET_CACHE_CONNECTION_LIST"]="SET_CACHE_CONNECTION_LIST",e["REFRESH_TABLE"]="REFRESH_TABLE",e["ADD_QUERY_LOG"]="ADD_QUERY_LOG"})(a||(a={}));var A,j,x,I=(r={},Object(i["a"])(r,a.REFRESH_TABLE,(function(e){e.refreshTable=!0,e.refreshTable=!1})),Object(i["a"])(r,a.SET_INFO,(function(e,t){return e.info=t})),Object(i["a"])(r,a.SET_GRANTS,(function(e,t){return e.grants=t})),Object(i["a"])(r,a.SET_SCHEMAS,(function(e,t){return e.init.schemas=t})),Object(i["a"])(r,a.SET_ROLES,(function(e,t){return e.init.roles=t})),Object(i["a"])(r,a.SELECT_SCHEMAS,(function(e,t){return e.selected.schemas=t})),Object(i["a"])(r,a.SELECT_ROLES,(function(e,t){return e.selected.roles=t})),Object(i["a"])(r,a.RESET_SELECTED,(function(e){return e.selected.roles=[],e.selected.schemas=[],e})),Object(i["a"])(r,a.SET_CONFIG_IGNORE,(function(e,t){return e.config.ignorePg=t})),Object(i["a"])(r,a.SET_CACHE_STATUS,(function(e,t){return e.config.cache.hasCached=t})),Object(i["a"])(r,a.SET_CACHE_CONNECTION,(function(e,t){return e.config.cache.currentConnection=t})),Object(i["a"])(r,a.SET_CACHE_CONNECTION_LIST,(function(e,t){return e.config.cache.connectionList=t})),Object(i["a"])(r,a.ADD_QUERY_LOG,(function(e,t){return e.queryLog.push({sql:t,date:new Date})})),r),L=n("2f62"),G=n("75fc"),P=n("768b");n("ac4d"),n("8a81"),n("4f7f"),n("ffc1"),n("4917"),n("28a5"),n("f559"),n("5df3"),n("f400");function M(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function U(e){for(var t=1;t1?e:"public.".concat(e)},X=function(e){var t=/EXECUTE (PROCEDURE|FUNCTION) ([\w\.]+)\(/;if(!t.test(e))return null;var n=e.match(t)[2];return W(n)},K=function(e){var t=X(e.action_statement),n=e.action_timing,r=e.trigger_name,a=e.trigger_schema,s=e.event_manipulation,c=e.event_object_schema,o=e.event_object_table;return{label:"".concat(a,".").concat(r),functionTarget:t,tableTarget:"".concat(c,".").concat(o),meta:{actionTiming:n,eventManipulation:s}}},ee=function(e,t,n,r){var a=arguments.length>4&&void 0!==arguments[4]?arguments[4]:null,s=new Map([[x.TABLE,0],[x.COLUMN,1],[x.ROUTINE,2],[x.TRIGGER,1],[x.OBJECT,1]]);return{type:e,label:t,grants:n,meta:r,level:null===a?s.get(e):a}},te=(A={},Object(i["a"])(A,j.CONNECTION_LIST,(function(e){var t=e.config.cache.connectionList;return t?Object.entries(t):null})),Object(i["a"])(A,j.SCHEMA_LIST,(function(e){return Z(e.init.schemas,e.config.ignorePg)})),Object(i["a"])(A,j.ROLE_LIST,(function(e){return Z(e.init.roles,e.config.ignorePg)})),Object(i["a"])(A,j.GRANT_COLUMN_MAP,(function(e){return Y(e.grants.columns,e.selected.roles,H)})),Object(i["a"])(A,j.GRANT_TABLE_MAP,(function(e){return Y(e.grants.tables,e.selected.roles,D)})),Object(i["a"])(A,j.GRANT_ROUTINE_MAP,(function(e){return Y(e.grants.routines,e.selected.roles,B)})),Object(i["a"])(A,j.GRANT_OBJECT_MAP,(function(e){return Y(e.grants.objects,e.selected.roles,$)})),Object(i["a"])(A,j.TABLE_COLUMN_MAP,(function(e){return J(e.info.columns)})),Object(i["a"])(A,j.TABLE_SET,(function(e){return new Set(e.info.tables.map(D))})),Object(i["a"])(A,j.ROUTINE_SET,(function(e){return new Set(e.info.routines.map(B))})),Object(i["a"])(A,j.ENTITY_TREE,(function(e,t){var n=V(e.selected.roles),r=e.info.tables.length>0,a=e.info.columns.length>0,s=e.selected.roles.length>0;if(!a||!r||!s)return[];var c=[],o=t[j.GRANT_TABLE_MAP],i=t[j.GRANT_COLUMN_MAP],l=t[j.GRANT_ROUTINE_MAP],u=t[j.TRIGGER_MAP],f=!0,d=!1,p=void 0;try{for(var h,m=t[j.ROUTINE_SET][Symbol.iterator]();!(f=(h=m.next()).done);f=!0){var E=h.value,g=l.has(E);if(g){var C=l.get(E);c.push(ee(x.ROUTINE,E,C,{sql:"{:action} {:grant} ON FUNCTION ".concat(E)}))}else c.push(ee(x.ROUTINE,E,n,{sql:"{:action} {:grant} ON FUNCTION ".concat(E)}))}}catch(ae){d=!0,p=ae}finally{try{f||null==m.return||m.return()}finally{if(d)throw p}}var b=!0,v=!1,_=void 0;try{for(var O,T=t[j.TABLE_COLUMN_MAP][Symbol.iterator]();!(b=(O=T.next()).done);b=!0){var y=Object(P["a"])(O.value,2),N=y[0],S=y[1],w=o.has(N);if(w){var R=o.get(N);c.push(ee(x.TABLE,N,R,{sql:"{:action} {:grant} ON TABLE ".concat(N)}))}else c.push(ee(x.TABLE,S.label,n,{sql:"{:action} {:grant} ON TABLE ".concat(S.label)}));var A=u.has(N);if(A){var I=u.get(N),L=!0,G=!1,M=void 0;try{for(var k,F=I[Symbol.iterator]();!(L=(k=F.next()).done);L=!0){var H=k.value,D=H.label,B=H.functionTarget,$=H.meta;if(c.push(ee(x.TRIGGER,D,n,U({},$,{sql:"{:action} {:grant} ON SEQUENCE ".concat(D)}))),null!==B){var q=l.has(B);if(q){var z=l.get(B);c.push(ee(x.ROUTINE,B,z,{sql:"{:action} {:grant} ON FUNCTION ".concat(B)}))}else c.push(ee(x.ROUTINE,B,n,{sql:"{:action} {:grant} ON FUNCTION ".concat(B)}))}}}catch(ae){G=!0,M=ae}finally{try{L||null==F.return||F.return()}finally{if(G)throw M}}}var Q=!0,Y=!1,J=void 0;try{for(var Z,W=S.columns[Symbol.iterator]();!(Q=(Z=W.next()).done);Q=!0){var X=Object(P["a"])(Z.value,2),K=X[0],te=X[1],ne=i.has(K);if(ne){var re=i.get(K);c.push(ee(x.COLUMN,te.label,re,{sql:"{:action} {:grant} (".concat(te.columnName,") ON TABLE ").concat(S.label)}))}else c.push(ee(x.COLUMN,te.label,n,{sql:"{:action} {:grant} (".concat(te.columnName,") ON TABLE ").concat(S.label)}))}}catch(ae){Y=!0,J=ae}finally{try{Q||null==W.return||W.return()}finally{if(Y)throw J}}}}catch(ae){v=!0,_=ae}finally{try{b||null==T.return||T.return()}finally{if(v)throw _}}return c})),Object(i["a"])(A,j.TRIGGER_MAP,(function(e){var t=new Map;return e.info.triggers.forEach((function(e){var n=q(e),r=K(e);t.has(n)?t.set(n,[].concat(Object(G["a"])(t.get(n)),[r])):t.set(n,[r])})),t})),A),ne="/api",re=function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(t,n){var r,a,s,c,o=arguments;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return r=o.length>2&&void 0!==o[2]?o[2]:"POST",a="POST"===r,s=a?{"Content-Type":"application/json"}:{},c=a?JSON.stringify(n):null,e.next=6,fetch("".concat(ne).concat(t),{method:r,headers:s,body:c}).then((function(e){return e.json()}));case 6:return e.abrupt("return",e.sent);case 7:case"end":return e.stop()}}),e)})));return function(t,n){return e.apply(this,arguments)}}();(function(e){e["INIT"]="init",e["FETCH_DATA"]="fetchData",e["GET_INFO"]="getInfo",e["GET_GRANTS"]="getGrants",e["GET_CACHED_CONNECTIONS"]="getCachedClients",e["GET_CURRENT_CONNECTION"]="getCurrentConnection",e["NEW_CONNECTION"]="newConnection",e["REMOVE_CONNECTION"]="removeConnection",e["SET_CONNECTION"]="setConnection",e["RUN_QUERY"]="runQuery",e["REFRESH_DATA"]="refreshData"})(F||(F={}));var ae=(k={},Object(i["a"])(k,F.INIT,function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(t){var n;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return n=t.dispatch,n(F.GET_CURRENT_CONNECTION),n(F.GET_CACHED_CONNECTIONS),e.abrupt("return",n(F.FETCH_DATA));case 4:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),Object(i["a"])(k,F.GET_CURRENT_CONNECTION,function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(t){var n,r;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return n=t.commit,e.next=3,re("/cache/current",null,"GET");case 3:r=e.sent,"notCached"in r?(n(a.SET_CACHE_STATUS,!1),n(a.SET_CACHE_CONNECTION,null)):(n(a.SET_CACHE_STATUS,!0),n(a.SET_CACHE_CONNECTION,r.currentId));case 5:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),Object(i["a"])(k,F.FETCH_DATA,function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(t){var n,r;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return n=t.commit,e.next=3,re("/info/init",null,"GET");case 3:return r=e.sent,"noConfig"in r||(n(a.SET_SCHEMAS,r.schemas),n(a.SET_ROLES,r.roles)),e.abrupt("return",r);case 6:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),Object(i["a"])(k,F.GET_INFO,function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(t,n){var r,s,c;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return r=t.commit,s=n.schemas,r(a.SELECT_SCHEMAS,s),e.next=5,re("/info",{schemas:s});case 5:c=e.sent,r(a.SET_INFO,c);case 7:case"end":return e.stop()}}),e)})));return function(t,n){return e.apply(this,arguments)}}()),Object(i["a"])(k,F.GET_GRANTS,function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(t,n){var r,s,c;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return r=t.commit,s=n.grantees,r(a.SELECT_ROLES,s),e.next=5,re("/grants",{grantees:s});case 5:c=e.sent,r(a.SET_GRANTS,c);case 7:case"end":return e.stop()}}),e)})));return function(t,n){return e.apply(this,arguments)}}()),Object(i["a"])(k,F.GET_CACHED_CONNECTIONS,function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(t){var n,r;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return n=t.commit,e.next=3,re("/cache/connections",null,"GET");case 3:r=e.sent,n(a.SET_CACHE_CONNECTION_LIST,r);case 5:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),Object(i["a"])(k,F.NEW_CONNECTION,function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(t,n){var r,s,c,o;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return r=t.commit,s=n.connection,e.next=4,re("/cache/newConnection",{connection:s});case 4:c=e.sent,o=c.connections,r(a.SET_CACHE_CONNECTION_LIST,o);case 7:case"end":return e.stop()}}),e)})));return function(t,n){return e.apply(this,arguments)}}()),Object(i["a"])(k,F.REMOVE_CONNECTION,function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(t){var n,r,s,c;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return n=t.commit,r=t.state,e.next=3,re("/cache/removeConnection",{connectionId:r.config.cache.currentConnection});case 3:s=e.sent,c=s.connections,n(a.SET_CACHE_CONNECTION_LIST,c),n(a.SET_CACHE_CONNECTION,null);case 7:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}()),Object(i["a"])(k,F.SET_CONNECTION,function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(t,n){var r,s,c;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return r=t.commit,s=t.dispatch,c=n.connectionId,e.next=4,re("/cache/setConnection",{connectionId:c});case 4:r(a.RESET_SELECTED),r(a.SET_CACHE_CONNECTION,c),s(F.FETCH_DATA);case 7:case"end":return e.stop()}}),e)})));return function(t,n){return e.apply(this,arguments)}}()),Object(i["a"])(k,F.REFRESH_DATA,function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(t,n){var r,a,s;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return r=t.dispatch,a=n.schemas,s=n.grantees,e.next=4,r(F.GET_INFO,{schemas:a});case 4:return e.next=6,r(F.GET_GRANTS,{grantees:s});case 6:return e.next=8,r(F.FETCH_DATA);case 8:case"end":return e.stop()}}),e)})));return function(t,n){return e.apply(this,arguments)}}()),Object(i["a"])(k,F.RUN_QUERY,function(){var e=Object(l["a"])(regeneratorRuntime.mark((function e(t,n){var r,s,c,o,i;return regeneratorRuntime.wrap((function(e){while(1)switch(e.prev=e.next){case 0:return r=t.dispatch,s=t.commit,c=n.sql,o=n.schemas,i=n.grantees,e.next=4,re("/info/query",{sql:c});case 4:s(a.ADD_QUERY_LOG,c),r(F.REFRESH_DATA,{schemas:o,grantees:i});case 6:case"end":return e.stop()}}),e)})));return function(t,n){return e.apply(this,arguments)}}()),k);function se(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function ce(e){for(var t=1;t0;this.$store.commit(a.SET_CONFIG_IGNORE,n)}},methods:{handleConnectionChange:function(){this.$store.dispatch(F.SET_CONNECTION,{connectionId:this.selectedConnection})},handleRemoveConnection:function(){this.$store.dispatch(F.REMOVE_CONNECTION)}},components:{ZCheckbox:S,ZFieldset:v}}),ie=oe,le=Object(C["a"])(ie,d,p,!1,null,null,null),ue=le.exports,fe=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"bg-white m-3 rounded-lg pb-2"},[n("div",{staticClass:"font-display flex items-center justify-between p-2"},[n("div",{class:e.titleClass,on:{click:e.showBody}},[e._v(e._s(e.title))]),n("div",[e.hasCollapse?n("fa-icon",{staticClass:"text-gray-400 cursor-pointer hover:text-gray-600",attrs:{icon:e.fontName},on:{click:e.handleCollapse}}):e._e(),e.hasClose?n("fa-icon",{staticClass:"text-gray-400 cursor-pointer hover:text-gray-600",attrs:{icon:"times-circle"},on:{click:function(t){return e.$emit("close-card")}}}):e._e()],1)]),e.isCollapsed?e._e():n("div",{staticClass:"font-body"},[e._t("default"),e._t("action")],2)])},de=[],pe=s["a"].extend({name:"z-card",props:{title:String,collapsed:{type:Boolean,default:!1},hasCollapse:{type:Boolean,default:!0},hasClose:{type:Boolean,default:!1}},mounted:function(){this.isCollapsed=this.collapsed},data:function(){return{isCollapsed:!1}},computed:{fontName:function(){return this.isCollapsed?"plus-circle":"minus-circle"},titleClass:function(){return{"text-gray-800":!this.isCollapsed,"text-gray-600 cursor-pointer":this.isCollapsed}}},methods:{handleCollapse:function(){this.isCollapsed=!this.isCollapsed},showBody:function(){this.isCollapsed&&this.handleCollapse()}}}),he=pe,me=Object(C["a"])(he,fe,de,!1,null,null,null),Ee=me.exports,ge=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"flex items-center"},[e.hasGrants?e._l(e.entityGrants,(function(t,r){return n("div",{directives:[{name:"tooltip",rawName:"v-tooltip",value:t,expression:"grant"}],key:r,staticClass:"text-xs h-5 w-4 text-white mr-1 rounded-sm text-center select-none",class:e.grantClass(t),on:{click:function(n){return e.handleGrantClick(t)}}},[e._v(e._s(t.slice(0,1)))])})):[n("div",{staticClass:"w-10 h-1 bg-gray-400 rounded"})]],2)},Ce=[],be=(n("a481"),s["a"].extend({name:"z-entity-grant",props:{type:String,grants:Array,entity:Object,role:String,meta:Object},data:function(){var e;return{allGrants:(e={},Object(i["a"])(e,x.TABLE,["SELECT","INSERT","UPDATE","DELETE","TRUNCATE","REFERENCES","TRIGGER"]),Object(i["a"])(e,x.COLUMN,["SELECT","INSERT","UPDATE","REFERENCES"]),Object(i["a"])(e,x.OBJECT,["USAGE"]),Object(i["a"])(e,x.ROUTINE,["EXECUTE"]),Object(i["a"])(e,x.TRIGGER,[]),e)}},computed:{entityGrants:function(){return this.allGrants[this.type]},hasGrants:function(){return this.entityGrants.length>0}},methods:{hasGrant:function(e){return this.grants.includes(e)},grantClass:function(e){return{"bg-green-400 hover:bg-green-500":this.hasGrant(e),"bg-gray-400 hover:bg-gray-500":!this.hasGrant(e)}},handleGrantClick:function(e){this.hasGrant(e);var t=this.hasGrant(e)?"REVOKE":"GRANT",n=this.hasGrant(e)?"FROM":"TO",r=this.meta.sql.replace("{:action}",t).replace("{:grant}",e).concat(" ".concat(n," ").concat(this.role));this.$emit("run-query",r)}}})),ve=be,_e=Object(C["a"])(ve,ge,Ce,!1,null,null,null),Oe=_e.exports,Te=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"flex rounded items-center mt-1",class:e.wrapClass},[n("div",{staticClass:"w-header__title",class:e.titleStyle},[n("div",{staticClass:"row__head w-100 text-gray-600 bg-gray-300 select-none",class:e.titleFont},[n("fa-icon",{directives:[{name:"tooltip",rawName:"v-tooltip",value:e.type,expression:"type"}],staticClass:"mr-2",attrs:{icon:e.iconFont}}),e._v(e._s(e.title)),e.hasMeta?n("span",{staticClass:"text-xs ml-2 bg-gray-500 text-gray-800 p-1 rounded"},[e._v(e._s(Object.values(e.meta).join(" ")))]):e._e()],1)]),n("div",{staticClass:"row__data flex justify-around p-2 flex-grow text-gray-700 bg-gray-200 rounded-r",class:e.slotClass},[e._t("default")],2)])},ye=[],Ne=(n("c5f6"),s["a"].extend({name:"z-manage-row",props:{title:String,type:String,meta:{type:Object,default:void 0},level:{type:Number,default:0},isSticky:{type:Boolean,default:!1}},computed:{hasMeta:function(){return!(this.meta&&"sql"in this.meta)&&void 0!==this.meta},iconFont:function(){var e=new Map([[x.TABLE,"table"],[x.COLUMN,"columns"],[x.ROUTINE,"code"],[x.TRIGGER,"bolt"],[x.OBJECT,"box"],["header","users"]]);return e.get(this.type)},titleStyle:function(){return{"pl-0":0===this.level,"pl-4":1===this.level,"pl-8":2===this.level}},titleFont:function(){return{"text-sm":this.level>0,"bg-gray-400 text-gray-700":0===this.level,"bg-gray-300":1===this.level,"rounded-l":!this.isSticky,"rounded-tl":this.isSticky,"h-10 p-2":0===this.level,"h-8 p-1 pl-2":this.level>0}},slotClass:function(){return{"rounded-r":!this.isSticky,"rounded-tr":this.isSticky,"h-10":0===this.level,"h-8":this.level>0}},wrapClass:function(){return{"border-b-4 border-gray-500":this.isSticky,row__hover:"header"!==this.type}}}})),Se=Ne,we=(n("e665"),Object(C["a"])(Se,Te,ye,!1,null,null,null)),Re=we.exports,Ae=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("form",{staticClass:"px-2",on:{submit:function(t){return t.preventDefault(),e.addNewConnection(t)}}},[n("div",{staticClass:"flex justify-between"},[n("z-fieldset",{staticClass:"mr-2 w-1/2",attrs:{label:"User"}},[n("input",{directives:[{name:"model",rawName:"v-model",value:e.connection.user,expression:"connection.user"}],staticClass:"input--basic",attrs:{type:"text",required:""},domProps:{value:e.connection.user},on:{input:function(t){t.target.composing||e.$set(e.connection,"user",t.target.value)}}})]),n("z-fieldset",{staticClass:"w-1/2",attrs:{label:"Password"}},[n("input",{directives:[{name:"model",rawName:"v-model",value:e.connection.password,expression:"connection.password"}],staticClass:"input--basic",attrs:{type:"password",required:""},domProps:{value:e.connection.password},on:{input:function(t){t.target.composing||e.$set(e.connection,"password",t.target.value)}}})])],1),n("div",{staticClass:"flex justify-between"},[n("z-fieldset",{staticClass:"mr-2 w-1/2",attrs:{label:"Host"}},[n("input",{directives:[{name:"model",rawName:"v-model",value:e.connection.host,expression:"connection.host"}],staticClass:"input--basic",attrs:{type:"text",placeholder:"127.0.0.1",required:""},domProps:{value:e.connection.host},on:{input:function(t){t.target.composing||e.$set(e.connection,"host",t.target.value)}}})]),n("z-fieldset",{staticClass:"w-1/2",attrs:{label:"Port"}},[n("input",{directives:[{name:"model",rawName:"v-model.number",value:e.connection.port,expression:"connection.port",modifiers:{number:!0}}],staticClass:"input--basic",attrs:{type:"number",placeholder:"5432",required:""},domProps:{value:e.connection.port},on:{input:function(t){t.target.composing||e.$set(e.connection,"port",e._n(t.target.value))},blur:function(t){return e.$forceUpdate()}}})])],1),n("div",{staticClass:"w-full"},[n("z-fieldset",{attrs:{label:"Database"}},[n("input",{directives:[{name:"model",rawName:"v-model",value:e.connection.database,expression:"connection.database"}],staticClass:"input--basic",attrs:{type:"text",required:""},domProps:{value:e.connection.database},on:{input:function(t){t.target.composing||e.$set(e.connection,"database",t.target.value)}}})])],1),e._m(0)])},je=[function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{staticClass:"action__bar mt-2 border-t"},[n("div",{staticClass:"py-2"},[n("button",{staticClass:"button--basic",attrs:{type:"submit"}},[e._v("Add")])])])}],xe=s["a"].extend({name:"z-form-connection",data:function(){return{connection:{user:"",password:"",host:"",port:"",database:""}}},methods:{addNewConnection:function(){this.$store.dispatch(F.NEW_CONNECTION,{connection:this.connection}),this.connection={user:"",password:"",host:"",port:"",database:""}}},components:{ZFieldset:v}}),Ie=xe,Le=Object(C["a"])(Ie,Ae,je,!1,null,null,null),Ge=Le.exports;function Pe(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function Me(e){for(var t=1;t337?n.app.showStickyHeader=!0:n.app.showStickyHeader=!1}),{passive:!0});case 6:case"end":return e.stop()}}),e,this)})));function t(){return e.apply(this,arguments)}return t}(),data:function(){return{selectedRoles:[],selectedSchemas:[],selectedEntities:["Tables","Columns","Objects","Routines","Triggers"],app:{showStickyHeader:!1,showQueryLog:!1,showAddConnection:!1,noConfig:!0},config:{manage:[{label:"Tables",value:x.TABLE},{label:"Columns",value:x.COLUMN},{label:"Objects",value:x.OBJECT},{label:"Routines",value:x.ROUTINE},{label:"Triggers",value:x.TRIGGER}]},filterCache:[],entityForm:{name:"",type:"ROLE"}}},watch:{selectedSchemas:function(e,t){e.length&&this.$store.dispatch(F.GET_INFO,{schemas:e})},selectedRoles:function(e,t){e.length&&this.$store.dispatch(F.GET_GRANTS,{grantees:e})}},computed:Me({},Object(L["c"])(["init","selected","queryLog"]),{},Object(L["b"])([j.ENTITY_TREE,j.SCHEMA_LIST,j.ROLE_LIST]),{hasSelected:function(){return this.selectedSchemas.length>0&&this.selectedRoles.length>0},headerClass:function(){return{"fixed w-header top-0 mt-1":this.app.showStickyHeader,"w-full":!this.app.showStickyHeader}},filteredEntities:function(){var e=this,t=this.config.manage.filter((function(t){return e.selectedEntities.includes(t.label)})).map((function(e){return e.value}));return this.entityTree.filter((function(e){return t.includes(e.type)}))}}),methods:{runQuery:function(e){this.$store.dispatch(F.RUN_QUERY,{sql:e,schemas:this.selectedSchemas,grantees:this.selectedRoles})},handleAddEntity:function(){var e="CREATE ".concat(this.entityForm.type," ").concat(this.entityForm.name),t=this.selectedSchemas||[],n=this.selectedRoles||[];this.$store.dispatch(F.RUN_QUERY,{sql:e,schemas:t,grantees:n}),this.entityForm.name=""}},components:{NavBar:ue,ZCheckbox:S,ZCard:Ee,ZEntityGrant:Oe,ZManageRow:Re,ZFieldset:v,ZFormConnection:Ge,draggable:f.a}}),ke=Ue,Fe=(n("034f"),Object(C["a"])(ke,c,o,!1,null,null,null)),He=Fe.exports,De=n("bfa9"),Be={refreshTable:!1,config:{ignorePg:!0,cache:{hasCached:!1,currentConnection:null,connectionList:null}},selected:{schemas:[],roles:[]},init:{schemas:[],roles:[]},info:{columns:[],roles:[],tables:[],triggers:[],routines:[]},grants:{columns:[],objects:[],routines:[],tables:[]},queryLog:[]};s["a"].use(L["a"]);var $e=new De["a"]({storage:window.localStorage,reducer:function(e){return{config:e.config,selected:e.selected}}}),qe=new L["a"].Store({state:Be,mutations:I,actions:ae,getters:te,plugins:[$e.plugin]}),ze=(n("77ed"),n("def6"),n("fd44"),n("5aea"),n("e37d")),Qe=n("ecee"),Ye=n("c074"),Je=n("b702"),Ze=n("ad3d");Qe["c"].add(Ye["f"],Je["a"],Ye["m"],Ye["n"],Ye["h"],Ye["g"],Ye["c"],Ye["d"],Ye["q"],Ye["j"],Ye["l"],Ye["b"],Ye["e"],Ye["a"],Ye["o"],Ye["k"],Ye["i"],Ye["p"]),s["a"].use(ze["a"]),s["a"].component("fa-icon",Ze["a"]),s["a"].config.productionTip=!1,new s["a"]({store:qe,render:function(e){return e(He)}}).$mount("#app")},def6:function(e,t,n){},e665:function(e,t,n){"use strict";var r=n("297b"),a=n.n(r);a.a},f7aa:function(e,t,n){"use strict";var r=n("0089"),a=n.n(r);a.a},fd44:function(e,t,n){}});
2 | //# sourceMappingURL=app.dc8ec42f.js.map
--------------------------------------------------------------------------------
/dist/js/app.dc8ec42f.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/App.vue?5b85","webpack:///./src/store/mutations.ts","webpack:///./src/App.vue?0feb","webpack:///./src/components/NavBar.vue?c7f4","webpack:///./src/components/layout/Fieldset.vue?9a66","webpack:///./src/components/layout/Fieldset.vue?d680","webpack:///./src/components/layout/Fieldset.vue?63ff","webpack:///./src/components/layout/Fieldset.vue","webpack:///./src/components/layout/Checkbox.vue?c0a9","webpack:///./src/components/layout/Checkbox.vue?102d","webpack:///./src/components/layout/Checkbox.vue?6dc8","webpack:///./src/components/layout/Checkbox.vue","webpack:///./src/utils/toggleArray.ts","webpack:///./src/store/getters.ts","webpack:///./src/store/actions.ts","webpack:///./src/utils/http-api.ts","webpack:///./src/components/NavBar.vue?e540","webpack:///./src/components/NavBar.vue?6c7f","webpack:///./src/components/NavBar.vue","webpack:///./src/components/Card.vue?7e03","webpack:///./src/components/Card.vue?3755","webpack:///./src/components/Card.vue?fa9f","webpack:///./src/components/Card.vue","webpack:///./src/components/EntityGrant.vue?8bf3","webpack:///./src/components/EntityGrant.vue?1ac5","webpack:///./src/components/EntityGrant.vue?4239","webpack:///./src/components/EntityGrant.vue","webpack:///./src/components/ManageRow.vue?7b43","webpack:///./src/components/ManageRow.vue?954e","webpack:///./src/components/ManageRow.vue?c02e","webpack:///./src/components/ManageRow.vue","webpack:///./src/components/FormConnection.vue?ca51","webpack:///./src/components/FormConnection.vue?02c8","webpack:///./src/components/FormConnection.vue?5b9c","webpack:///./src/components/FormConnection.vue","webpack:///./src/App.vue?ec60","webpack:///./src/App.vue?640d","webpack:///./src/App.vue","webpack:///./src/store/state.ts","webpack:///./src/store/index.ts","webpack:///./src/main.ts","webpack:///./src/components/ManageRow.vue?e9a6","webpack:///./src/components/layout/Checkbox.vue?a959"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","exports","module","l","m","c","d","name","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","p","jsonpArray","window","oldJsonpFunction","slice","Mutations","_vm","this","_h","$createElement","_c","_self","staticClass","attrs","on","$event","app","showQueryLog","showAddConnection","_v","_l","log","index","_s","date","toISOString","sql","_e","preventDefault","handleAddEntity","directives","rawName","entityForm","expression","domProps","target","composing","$set","$$selectedVal","Array","filter","options","selected","map","val","_value","multiple","label","selectedRoles","toggleArray","selectedSchemas","ref","hasSelected","config","item","selectedEntities","class","headerClass","showStickyHeader","role","entity","level","type","meta","grants","roleName","runQuery","staticRenderFns","_m","clientList","selectedConnection","handleConnectionChange","client","_f","$emit","handleRemoveConnection","ignorePg","_t","extend","props","String","component","wrapColors","iconFont","computed","isSelected","includes","array","findIndex","toggleArrayMixin","methods","Getters","EntityTypes","mutations","REFRESH_TABLE","state","refreshTable","SET_INFO","info","SET_GRANTS","SET_SCHEMAS","schemas","init","SET_ROLES","roles","SELECT_SCHEMAS","SELECT_ROLES","RESET_SELECTED","SET_CONFIG_IGNORE","isIgnore","SET_CACHE_STATUS","status","cache","hasCached","SET_CACHE_CONNECTION","currentConnection","SET_CACHE_CONNECTION_LIST","connectionList","ADD_QUERY_LOG","queryLog","Date","Actions","columnKey","table_schema","table_name","column_name","tableKey","routineKey","routine_schema","routine_name","objectKey","object_schema","object_name","triggerKey","trigger_schema","event_object_table","columnLabel","tableLabel","generateGrantMap","arr","keyFn","Map","forEach","id","has","set","grantee","entityGrants","privilege_type","generateColumnMap","tableId","columnId","columns","tableMap","columnName","filterPg","list","hasIgnore","startsWith","emptyGrants","reduce","acc","parseFunctionName","parts","split","parseTriggerStatement","statement","matchFunction","test","functionName","match","parseTrigger","trigger","functionTarget","action_statement","action_timing","trigger_name","event_manipulation","event_object_schema","tableTarget","actionTiming","eventManipulation","entityRow","entityLevels","TABLE","COLUMN","ROUTINE","TRIGGER","OBJECT","getters","CONNECTION_LIST","entries","SCHEMA_LIST","ROLE_LIST","GRANT_COLUMN_MAP","GRANT_TABLE_MAP","tables","GRANT_ROUTINE_MAP","routines","GRANT_OBJECT_MAP","objects","TABLE_COLUMN_MAP","TABLE_SET","Set","ROUTINE_SET","ENTITY_TREE","storeGetters","EMPTY_GRANTS","hasTables","hasColumns","hasSelectedRoles","mapTableGrants","mapColumnGrants","mapRoutineGrants","mapTriggers","TRIGGER_MAP","routineId","hasRoutineGrants","routineGrants","tableInfo","hasTableGrants","tableGrants","hasTriggers","tableTriggers","hasFunctionGrants","functionGrants","columnInfo","hasColumnGrants","columnGrants","triggers","API_ENDPOINT","httpApi","endpoint","method","isPost","headers","body","JSON","stringify","fetch","then","res","json","actions","INIT","dispatch","GET_CURRENT_CONNECTION","GET_CACHED_CONNECTIONS","FETCH_DATA","commit","cachedClient","currentId","initInfo","GET_INFO","GET_GRANTS","grantees","connections","NEW_CONNECTION","connection","REMOVE_CONNECTION","connectionId","SET_CONNECTION","REFRESH_DATA","RUN_QUERY","mixins","filters","clientName","user","host","port","database","mounted","$store","watch","oldVal","components","ZCheckbox","ZFieldset","titleClass","showBody","title","fontName","handleCollapse","isCollapsed","collapsed","Boolean","default","hasCollapse","hasClose","grant","grantClass","handleGrantClick","allGrants","hasGrants","hasGrant","grantAction","grantPronoun","sqlQuery","replace","concat","wrapClass","titleStyle","titleFont","values","join","slotClass","undefined","Number","isSticky","hasMeta","fontMap","row__hover","addNewConnection","modifiers","_n","$forceUpdate","password","initResponse","noConfig","addEventListener","ev","scrollY","passive","manage","filterCache","filteredEntities","entityTypes","entityTree","e","NavBar","ZCard","ZEntityGrant","ZManageRow","ZFormConnection","draggable","use","vuexLocal","storage","localStorage","reducer","Store","plugins","plugin","add","productionTip","store","render","h","App","$mount"],"mappings":"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","file":"js/app.dc8ec42f.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t\"app\": 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// add entry module to deferred list\n \tdeferredModules.push([0,\"chunk-vendors\"]);\n \t// run deferred modules when ready\n \treturn checkDeferredModules();\n","import mod from \"-!../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../node_modules/cache-loader/dist/cjs.js??ref--0-0!../node_modules/vue-loader/lib/index.js??vue-loader-options!./App.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../node_modules/cache-loader/dist/cjs.js??ref--0-0!../node_modules/vue-loader/lib/index.js??vue-loader-options!./App.vue?vue&type=style&index=0&lang=css&\"","import { ActionTree, MutationTree } from 'vuex';\nimport { State } from './state';\n\nexport const enum Mutations {\n SET_INFO = 'SET_INFO',\n SET_GRANTS = 'SET_GRANTS',\n SET_SCHEMAS = 'SET_SCHEMAS',\n SET_ROLES = 'SET_ROLES',\n SELECT_SCHEMAS = 'SELECT_SCHEMAS',\n SELECT_ROLES = 'SELECT_ROLES',\n RESET_SELECTED = 'RESET_SELECTED',\n SET_CONFIG_IGNORE = 'SET_CONFIG_IGNORE',\n SET_CACHE_STATUS = 'SET_CACHE_STATUS',\n SET_CACHE_CONNECTION = 'SET_CACHE_CONNECTION',\n SET_CACHE_CONNECTION_LIST = 'SET_CACHE_CONNECTION_LIST',\n REFRESH_TABLE = 'REFRESH_TABLE',\n ADD_QUERY_LOG = 'ADD_QUERY_LOG',\n}\n\nexport const mutations: MutationTree = {\n [Mutations.REFRESH_TABLE]: (state) => {\n state.refreshTable = true;\n state.refreshTable = false;\n },\n [Mutations.SET_INFO]: (state, info) => (state.info = info),\n [Mutations.SET_GRANTS]: (state, grants) => (state.grants = grants),\n [Mutations.SET_SCHEMAS]: (state, schemas) => (state.init.schemas = schemas),\n [Mutations.SET_ROLES]: (state, roles) => (state.init.roles = roles),\n [Mutations.SELECT_SCHEMAS]: (state, schemas) =>\n (state.selected.schemas = schemas),\n [Mutations.SELECT_ROLES]: (state, roles) => (state.selected.roles = roles),\n [Mutations.RESET_SELECTED]: (state) => {\n state.selected.roles = [];\n state.selected.schemas = [];\n return state;\n },\n [Mutations.SET_CONFIG_IGNORE]: (state, isIgnore) =>\n (state.config.ignorePg = isIgnore),\n [Mutations.SET_CACHE_STATUS]: (state, status) =>\n (state.config.cache.hasCached = status),\n [Mutations.SET_CACHE_CONNECTION]: (state, client) =>\n (state.config.cache.currentConnection = client),\n [Mutations.SET_CACHE_CONNECTION_LIST]: (state, clientList) =>\n (state.config.cache.connectionList = clientList),\n [Mutations.ADD_QUERY_LOG]: (state, sql) =>\n state.queryLog.push({ sql, date: new Date() }),\n};\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"bg-primary-100 pb-2 font-body\",attrs:{\"id\":\"app\"}},[_c('nav-bar',{on:{\"show-query-log\":function($event){_vm.app.showQueryLog = true},\"add-connection\":function($event){_vm.app.showAddConnection = true}}}),_c('main',[_c('transition',{attrs:{\"enter-active-class\":\"animated slideInRight fast\",\"leave-active-class\":\"animated slideOutRight faster\"}},[(_vm.app.showQueryLog)?_c('div',{staticClass:\"query-log h-screen bg-gray-800 fixed top-0 right-0 shadow-lg w-1/2\",attrs:{\"tabindex\":\"0\"},on:{\"blur\":function($event){_vm.app.showQueryLog = false}}},[_c('div',{staticClass:\"flex justify-between items-center text-white\"},[_c('div',{staticClass:\"text-lg cursor-pointer p-2\",on:{\"click\":function($event){_vm.app.showQueryLog = false}}},[_c('fa-icon',{staticClass:\"mr-1\",attrs:{\"icon\":\"caret-right\"}}),_vm._v(\"Query Log\")],1)]),_c('div',{staticClass:\"p-2 h-full\"},[_c('pre',{staticClass:\"bg-white rounded p-1 h-full\"},_vm._l((_vm.queryLog),function(log,index){return _c('div',{key:index,staticClass:\"text-xs whitespace-normal\"},[_c('span',{staticClass:\"text-blue-500\"},[_vm._v(_vm._s(log.date.toISOString())+\": \")]),_vm._v(_vm._s(log.sql))])}),0)])]):_vm._e()]),(_vm.app.showAddConnection)?_c('z-card',{staticClass:\"mx-auto w-1/2\",attrs:{\"has-collapse\":false,\"has-close\":\"\",\"title\":\"Add new connection\"},on:{\"close-card\":function($event){_vm.app.showAddConnection = false}}},[_c('z-form-connection')],1):_vm._e(),_c('z-card',{attrs:{\"title\":\"Add role or schema\",\"collapsed\":true}},[_c('form',{staticClass:\"px-2\",on:{\"submit\":function($event){$event.preventDefault();return _vm.handleAddEntity($event)}}},[_c('div',{staticClass:\"flex justify-between\"},[_c('z-fieldset',{staticClass:\"mr-2 w-1/2\",attrs:{\"label\":\"Name\"}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.entityForm.name),expression:\"entityForm.name\"}],staticClass:\"input--basic\",attrs:{\"type\":\"text\"},domProps:{\"value\":(_vm.entityForm.name)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.$set(_vm.entityForm, \"name\", $event.target.value)}}})]),_c('z-fieldset',{staticClass:\"w-1/2\",attrs:{\"label\":\"Type\"}},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.entityForm.type),expression:\"entityForm.type\"}],staticClass:\"input--basic\",on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.$set(_vm.entityForm, \"type\", $event.target.multiple ? $$selectedVal : $$selectedVal[0])}}},[_c('option',{attrs:{\"value\":\"ROLE\"}},[_vm._v(\"Role\")]),_c('option',{attrs:{\"value\":\"SCHEMA\"}},[_vm._v(\"Schema\")])])])],1),_c('div',{staticClass:\"action__bar mt-2 border-t\"},[_c('div',{staticClass:\"py-2\"},[_c('button',{staticClass:\"button--basic\"},[_vm._v(\"Add\")])])])])]),_c('z-card',{attrs:{\"title\":\"Select Roles\"}},[_c('div',{staticClass:\"p-2\"},_vm._l((_vm.roleList),function(label,index){return _c('z-checkbox',{key:index,staticClass:\"mr-1 mb-1\",attrs:{\"label\":label,\"selected\":_vm.selectedRoles},on:{\"selected\":function($event){return _vm.toggleArray(_vm.selectedRoles, $event)}}})}),1)]),_c('z-card',{attrs:{\"title\":\"Select Schemas\"}},[_c('div',{staticClass:\"p-2\"},_vm._l((_vm.schemaList),function(label,index){return _c('z-checkbox',{key:index,staticClass:\"mr-1 mb-1\",attrs:{\"label\":label,\"selected\":_vm.selectedSchemas},on:{\"selected\":function($event){return _vm.toggleArray(_vm.selectedSchemas, $event)}}})}),1)]),_c('z-card',{ref:\"manageCard\",attrs:{\"title\":\"Manage\"}},[_c('div',{staticClass:\"px-2\"},[(!_vm.hasSelected)?_c('div',{staticClass:\"mt-2 text-yellow-600 text-lg bg-yellow-200 p-2 rounded\"},[_c('fa-icon',{staticClass:\"mr-2\",attrs:{\"icon\":\"exclamation-triangle\"}}),_vm._v(\"Please select a role and a schema to continue\")],1):_vm._e(),(_vm.hasSelected)?_c('div',{staticClass:\"mt-2\"},[_vm._l((_vm.config.manage),function(item,index){return _c('z-checkbox',{key:index,staticClass:\"mr-2\",attrs:{\"label\":item.label,\"selected\":_vm.selectedEntities},on:{\"selected\":function($event){return _vm.toggleArray(_vm.selectedEntities, $event)}}})}),_c('div',{class:_vm.headerClass},[_c('z-manage-row',{attrs:{\"title\":\"Roles\",\"is-sticky\":_vm.app.showStickyHeader,\"type\":\"header\"}},_vm._l((_vm.selectedRoles),function(role,index){return _c('div',{key:index},[_vm._v(_vm._s(role))])}),0)],1),_c('draggable',[_c('transition-group',_vm._l((_vm.filteredEntities),function(entity,index){return _c('z-manage-row',{key:((entity.label) + \"-\" + index),attrs:{\"title\":entity.label,\"level\":entity.level,\"type\":entity.type,\"meta\":entity.meta}},_vm._l((entity.grants),function(grants,roleName){return _c('z-entity-grant',{key:roleName,attrs:{\"type\":entity.type,\"grants\":grants,\"entity\":entity,\"role\":roleName,\"meta\":entity.meta},on:{\"run-query\":_vm.runQuery}})}),1)}),1)],1)],2):_vm._e()])])],1)],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('nav',{staticClass:\"flex justify-between items-center bg-primary-500\",attrs:{\"role\":\"navigation\",\"aria-label\":\"main navigation\"}},[_vm._m(0),_c('div',{staticClass:\"mr-3 flex items-center\"},[_c('div',{staticClass:\"mr-2 flex\"},[(_vm.clientList.length > 0)?_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.selectedConnection),expression:\"selectedConnection\"}],staticClass:\"input--full\",on:{\"change\":[function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.selectedConnection=$event.target.multiple ? $$selectedVal : $$selectedVal[0]},_vm.handleConnectionChange]}},_vm._l((_vm.clientList),function(client,index){return _c('option',{key:index,domProps:{\"value\":client[0]}},[_vm._v(_vm._s(_vm._f(\"clientName\")(client[1])))])}),0):_vm._e(),_c('button',{directives:[{name:\"tooltip\",rawName:\"v-tooltip\",value:(\"Add new database\"),expression:\"\\\"Add new database\\\"\"}],staticClass:\"button__nav--icon ml-1\",on:{\"click\":function($event){return _vm.$emit(\"add-connection\")}}},[_c('fa-icon',{staticClass:\"mr-1\",attrs:{\"icon\":\"plus\"}})],1),_c('button',{directives:[{name:\"tooltip\",rawName:\"v-tooltip\",value:(\"Remove database\"),expression:\"\\\"Remove database\\\"\"}],staticClass:\"button__nav--icon ml-1\",on:{\"click\":_vm.handleRemoveConnection}},[_c('fa-icon',{staticClass:\"mr-1\",attrs:{\"icon\":\"trash\"}})],1)]),_c('button',{directives:[{name:\"tooltip\",rawName:\"v-tooltip\",value:(\"Show queries\"),expression:\"\\\"Show queries\\\"\"}],staticClass:\"button__nav--icon\",on:{\"click\":function($event){return _vm.$emit(\"show-query-log\")}}},[_c('fa-icon',{attrs:{\"icon\":\"bolt\"}})],1),_c('z-checkbox',{staticClass:\"ml-2\",attrs:{\"label\":\"Ignore PG roles\",\"selected\":_vm.ignorePg},on:{\"selected\":function($event){return _vm.toggleArray(_vm.ignorePg, $event)}}})],1)])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"text-lg text-white p-3 font-display\"},[_vm._v(\"Postgres\"),_c('strong',[_vm._v(\"HR\")])])}]\n\nexport { render, staticRenderFns }","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('fieldset',{staticClass:\"border rounded border-gray-300 bg-gray-200 focus-within:bg-white focus-within:border-primary-400\"},[_c('legend',{staticClass:\"text-sm text-gray-700\"},[_vm._v(_vm._s(_vm.label)+\" \")]),_vm._t(\"default\")],2)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n\n\n\nimport Vue from 'vue';\nexport default Vue.extend({\n name: 'v-fieldset',\n props: {\n label: String,\n },\n});\n","import mod from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/ts-loader/index.js??ref--13-3!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Fieldset.vue?vue&type=script&lang=ts&\"; export default mod; export * from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/ts-loader/index.js??ref--13-3!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Fieldset.vue?vue&type=script&lang=ts&\"","import { render, staticRenderFns } from \"./Fieldset.vue?vue&type=template&id=0eef6f64&lang=pug&\"\nimport script from \"./Fieldset.vue?vue&type=script&lang=ts&\"\nexport * from \"./Fieldset.vue?vue&type=script&lang=ts&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"checkbox items-center p-2 inline-flex rounded pointer select-none cursor-pointer\",class:_vm.wrapColors,on:{\"click\":function($event){return _vm.$emit(\"selected\", _vm.label)}}},[_c('fa-icon',{staticClass:\"mr-1\",attrs:{\"icon\":_vm.iconFont}}),_c('div',{staticClass:\"text-sm\"},[_vm._v(_vm._s(_vm.label))])],1)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n\n\n\nimport Vue from 'vue';\nexport default Vue.extend({\n name: 'z-checkbox',\n props: {\n label: String as () => string,\n selected: Array as () => string[],\n },\n computed: {\n isSelected(): boolean {\n return this.selected.includes(this.label);\n },\n wrapColors(): Record {\n return {\n 'bg-gray-300 text-gray-700 hover:bg-gray-400': !this.isSelected,\n 'bg-green-300 text-green-700 hover:bg-green-400': this.isSelected,\n };\n },\n iconFont(): string[] {\n return this.isSelected ? ['fas', 'check-circle'] : ['far', 'circle'];\n },\n },\n});\n","import mod from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/ts-loader/index.js??ref--13-3!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Checkbox.vue?vue&type=script&lang=ts&\"; export default mod; export * from \"-!../../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../../node_modules/thread-loader/dist/cjs.js!../../../node_modules/babel-loader/lib/index.js!../../../node_modules/ts-loader/index.js??ref--13-3!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Checkbox.vue?vue&type=script&lang=ts&\"","import { render, staticRenderFns } from \"./Checkbox.vue?vue&type=template&id=eab987ae&scoped=true&lang=pug&\"\nimport script from \"./Checkbox.vue?vue&type=script&lang=ts&\"\nexport * from \"./Checkbox.vue?vue&type=script&lang=ts&\"\nimport style0 from \"./Checkbox.vue?vue&type=style&index=0&id=eab987ae&scoped=true&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n \"eab987ae\",\n null\n \n)\n\nexport default component.exports","export const toggleArray = (array: unknown[], item: unknown) => {\n if (!array.includes(item)) {\n array.push(item);\n } else {\n const index = array.findIndex((r) => r === item);\n array.splice(index, 1);\n }\n};\n\nexport const toggleArrayMixin = {\n methods: {\n toggleArray,\n },\n};\n","import { GetterTree } from 'vuex';\nimport { State } from './state';\nimport { InformationSchema } from '@/utils/@types-information';\n\nexport type EntityGrant = Record;\nexport type EntityMeta = Record;\nexport const enum Getters {\n CONNECTION_LIST = 'clientList',\n SCHEMA_LIST = 'schemaList',\n ROLE_LIST = 'roleList',\n TABLE_COLUMN_MAP = 'tableColumnMap',\n TABLE_SET = 'tableSet',\n ROUTINE_SET = 'routineSet',\n ENTITY_TREE = 'entityTree',\n GRANT_COLUMN_MAP = 'grantColumn',\n GRANT_TABLE_MAP = 'grantTable',\n GRANT_ROUTINE_MAP = 'grantRoutine',\n GRANT_OBJECT_MAP = 'grantObject',\n TRIGGER_MAP = 'triggerMap',\n}\nexport const enum EntityTypes {\n TABLE = 'table',\n COLUMN = 'column',\n ROUTINE = 'routine',\n OBJECT = 'object',\n TRIGGER = 'trigger',\n}\ninterface KeyItem {\n table_schema: string;\n table_name: string;\n column_name?: string;\n}\ninterface KeyRoutineItem {\n routine_schema: string;\n routine_name: string;\n}\ninterface KeyTriggerItem {\n trigger_name: string;\n trigger_schema: string;\n event_object_table: string;\n}\ninterface KeyObjectItem {\n object_name: string;\n object_schema: string;\n}\ninterface TriggerInfo {\n label: string;\n functionTarget: string | null;\n tableTarget: string;\n meta: {\n actionTiming: string;\n eventManipulation: InformationSchema.Types.Trigger;\n };\n}\nconst columnKey = (c: KeyItem) =>\n `${c.table_schema}.${c.table_name}.${c.column_name}`;\nconst tableKey = (t: KeyItem) => `${t.table_schema}.${t.table_name}`;\nconst routineKey = (r: KeyRoutineItem) =>\n `${r.routine_schema}.${r.routine_name}`;\nconst objectKey = (o: KeyObjectItem) => `${o.object_schema}.${o.object_name}`;\nconst triggerKey = (t: KeyTriggerItem) =>\n `${t.trigger_schema}.${t.event_object_table}`;\nconst columnLabel = (c: KeyItem) => `${c.table_name}.${c.column_name}`;\nconst tableLabel = tableKey;\n\nconst generateGrantMap = (\n arr: InformationSchema.BaseGrant[],\n roles: string[],\n keyFn: CallableFunction,\n) => {\n const map = new Map();\n arr.forEach((item) => {\n const id = keyFn(item);\n if (!map.has(id)) {\n map.set(id, {});\n }\n const role = item.grantee;\n const entityGrants = map.get(id)!;\n roles.forEach((r) => {\n if (!(r in entityGrants)) {\n entityGrants[r] = [];\n }\n });\n if (!(role in entityGrants)) {\n entityGrants[role] = [];\n }\n entityGrants[role].push(item.privilege_type);\n });\n return map;\n};\nconst generateColumnMap = (arr: any[]) => {\n const map = new Map();\n arr.forEach((item) => {\n const tableId = tableKey(item);\n const columnId = columnKey(item);\n if (!map.has(tableId)) {\n map.set(tableId, {\n label: tableLabel(item),\n columns: new Map(),\n });\n }\n const tableMap = map.get(tableId);\n tableMap.columns.set(columnId, {\n label: columnLabel(item),\n columnName: item.column_name,\n });\n });\n return map;\n};\nconst filterPg = (list: string[] | null, hasIgnore: boolean) =>\n hasIgnore && list ? list.filter((s) => !s.startsWith('pg_')) : list;\n\nconst emptyGrants = (roles: string[]) =>\n roles.reduce(\n (acc, r) => {\n acc[r] = [];\n return acc;\n },\n {} as EntityGrant,\n );\n\nconst parseFunctionName = (name: string): string => {\n const parts = name.split('.');\n return parts.length > 1 ? name : `public.${name}`;\n};\nconst parseTriggerStatement = (statement: string): string | null => {\n const matchFunction = /EXECUTE (PROCEDURE|FUNCTION) ([\\w\\.]+)\\(/;\n if (!matchFunction.test(statement)) {\n return null;\n }\n const functionName = statement.match(matchFunction)![2];\n return parseFunctionName(functionName);\n};\nconst parseTrigger = (\n trigger: InformationSchema.Default.Trigger,\n): TriggerInfo => {\n const functionTarget = parseTriggerStatement(trigger.action_statement);\n const {\n action_timing,\n trigger_name,\n trigger_schema,\n event_manipulation,\n event_object_schema,\n event_object_table,\n } = trigger;\n return {\n label: `${trigger_schema}.${trigger_name}`,\n functionTarget,\n tableTarget: `${event_object_schema}.${event_object_table}`,\n meta: {\n actionTiming: action_timing,\n eventManipulation: event_manipulation,\n },\n };\n};\nexport interface EntityRow {\n type: EntityTypes;\n level: number;\n label: string;\n grants: EntityGrant;\n meta?: any;\n}\nconst entityRow = (\n type: EntityTypes,\n label: string,\n grants: EntityGrant,\n meta?: Record,\n level: number | null = null,\n): EntityRow => {\n const entityLevels = new Map([\n [EntityTypes.TABLE, 0],\n [EntityTypes.COLUMN, 1],\n [EntityTypes.ROUTINE, 2],\n [EntityTypes.TRIGGER, 1],\n [EntityTypes.OBJECT, 1],\n ]);\n return {\n type,\n label,\n grants,\n meta,\n level: level === null ? entityLevels.get(type)! : level,\n };\n};\ntype TriggerMap = Map;\ntype GrantMap = Map;\nexport const getters: GetterTree = {\n [Getters.CONNECTION_LIST]: ({\n config: {\n cache: { connectionList },\n },\n }) => (connectionList ? Object.entries(connectionList!) : null),\n [Getters.SCHEMA_LIST]: (state) =>\n filterPg(state.init.schemas, state.config.ignorePg),\n [Getters.ROLE_LIST]: (state) =>\n filterPg(state.init.roles, state.config.ignorePg),\n [Getters.GRANT_COLUMN_MAP]: (state) =>\n generateGrantMap(state.grants.columns, state.selected.roles, columnKey),\n [Getters.GRANT_TABLE_MAP]: (state) =>\n generateGrantMap(state.grants.tables, state.selected.roles, tableKey),\n [Getters.GRANT_ROUTINE_MAP]: (state) =>\n generateGrantMap(\n state.grants.routines,\n state.selected.roles,\n routineKey,\n ),\n [Getters.GRANT_OBJECT_MAP]: (state) =>\n generateGrantMap(state.grants.objects, state.selected.roles, objectKey),\n [Getters.TABLE_COLUMN_MAP]: (state) =>\n generateColumnMap(state.info.columns),\n [Getters.TABLE_SET]: (state) => new Set(state.info.tables.map(tableKey)),\n [Getters.ROUTINE_SET]: (state) =>\n new Set(state.info.routines.map(routineKey)),\n [Getters.ENTITY_TREE]: (state, storeGetters) => {\n const EMPTY_GRANTS = emptyGrants(state.selected.roles);\n const hasTables = state.info.tables.length > 0;\n const hasColumns = state.info.columns.length > 0;\n const hasSelectedRoles = state.selected.roles.length > 0;\n if (!hasColumns || !hasTables || !hasSelectedRoles) {\n return [];\n }\n const result: EntityRow[] = [];\n const mapTableGrants: GrantMap = storeGetters[Getters.GRANT_TABLE_MAP];\n const mapColumnGrants: GrantMap =\n storeGetters[Getters.GRANT_COLUMN_MAP];\n const mapRoutineGrants: GrantMap =\n storeGetters[Getters.GRANT_ROUTINE_MAP];\n\n const mapTriggers: TriggerMap = storeGetters[Getters.TRIGGER_MAP];\n\n for (const routineId of storeGetters[Getters.ROUTINE_SET]) {\n const hasRoutineGrants = mapRoutineGrants.has(routineId);\n if (hasRoutineGrants) {\n const routineGrants = mapRoutineGrants.get(routineId)!;\n result.push(\n entityRow(EntityTypes.ROUTINE, routineId, routineGrants, {\n sql: `{:action} {:grant} ON FUNCTION ${routineId}`,\n }),\n );\n } else {\n result.push(\n entityRow(EntityTypes.ROUTINE, routineId, EMPTY_GRANTS, {\n sql: `{:action} {:grant} ON FUNCTION ${routineId}`,\n }),\n );\n }\n }\n for (const [tableId, tableInfo] of storeGetters[\n Getters.TABLE_COLUMN_MAP\n ]) {\n const hasTableGrants = mapTableGrants.has(tableId);\n if (hasTableGrants) {\n const tableGrants = mapTableGrants.get(tableId)!;\n result.push(\n entityRow(EntityTypes.TABLE, tableId, tableGrants, {\n sql: `{:action} {:grant} ON TABLE ${tableId}`,\n }),\n );\n } else {\n result.push(\n entityRow(\n EntityTypes.TABLE,\n tableInfo.label,\n EMPTY_GRANTS,\n {\n sql: `{:action} {:grant} ON TABLE ${\n tableInfo.label\n }`,\n },\n ),\n );\n }\n const hasTriggers = mapTriggers.has(tableId);\n if (hasTriggers) {\n const tableTriggers = mapTriggers.get(tableId)!;\n for (const trigger of tableTriggers) {\n const { label, functionTarget, meta } = trigger;\n result.push(\n entityRow(EntityTypes.TRIGGER, label, EMPTY_GRANTS, {\n ...meta,\n sql: `{:action} {:grant} ON SEQUENCE ${label}`,\n }),\n );\n if (functionTarget !== null) {\n const hasFunctionGrants = mapRoutineGrants.has(\n functionTarget,\n );\n if (hasFunctionGrants) {\n const functionGrants = mapRoutineGrants.get(\n functionTarget,\n )!;\n result.push(\n entityRow(\n EntityTypes.ROUTINE,\n functionTarget,\n functionGrants,\n {\n sql: `{:action} {:grant} ON FUNCTION ${functionTarget}`,\n },\n ),\n );\n } else {\n result.push(\n entityRow(\n EntityTypes.ROUTINE,\n functionTarget,\n EMPTY_GRANTS,\n {\n sql: `{:action} {:grant} ON FUNCTION ${functionTarget}`,\n },\n ),\n );\n }\n }\n }\n }\n\n for (const [columnId, columnInfo] of tableInfo.columns) {\n const hasColumnGrants = mapColumnGrants.has(columnId);\n if (hasColumnGrants) {\n const columnGrants = mapColumnGrants.get(columnId)!;\n result.push(\n entityRow(\n EntityTypes.COLUMN,\n columnInfo.label,\n columnGrants,\n {\n sql: `{:action} {:grant} (${\n columnInfo.columnName\n }) ON TABLE ${tableInfo.label}`,\n },\n ),\n );\n } else {\n result.push(\n entityRow(\n EntityTypes.COLUMN,\n columnInfo.label,\n EMPTY_GRANTS,\n {\n sql: `{:action} {:grant} (${\n columnInfo.columnName\n }) ON TABLE ${tableInfo.label}`,\n },\n ),\n );\n }\n }\n }\n return result;\n },\n [Getters.TRIGGER_MAP]: (state) => {\n const map = new Map();\n state.info.triggers.forEach((t) => {\n const id = triggerKey(t);\n const value = parseTrigger(t);\n if (!map.has(id)) {\n map.set(id, [value]);\n } else {\n map.set(id, [...map.get(id)!, value]);\n }\n });\n return map;\n },\n};\n","import { ActionTree } from 'vuex';\nimport { State } from './state';\nimport { httpApi } from '@/utils/http-api';\nimport { Mutations } from './mutations';\n\nexport const enum Actions {\n INIT = 'init',\n FETCH_DATA = 'fetchData',\n GET_INFO = 'getInfo',\n GET_GRANTS = 'getGrants',\n GET_CACHED_CONNECTIONS = 'getCachedClients',\n GET_CURRENT_CONNECTION = 'getCurrentConnection',\n NEW_CONNECTION = 'newConnection',\n REMOVE_CONNECTION = 'removeConnection',\n SET_CONNECTION = 'setConnection',\n RUN_QUERY = 'runQuery',\n REFRESH_DATA = 'refreshData',\n}\n\nexport const actions: ActionTree = {\n async [Actions.INIT]({ dispatch }) {\n dispatch(Actions.GET_CURRENT_CONNECTION);\n dispatch(Actions.GET_CACHED_CONNECTIONS);\n return dispatch(Actions.FETCH_DATA);\n },\n async [Actions.GET_CURRENT_CONNECTION]({ commit }) {\n const cachedClient = await httpApi('/cache/current', null, 'GET');\n if ('notCached' in cachedClient) {\n commit(Mutations.SET_CACHE_STATUS, false);\n commit(Mutations.SET_CACHE_CONNECTION, null);\n } else {\n commit(Mutations.SET_CACHE_STATUS, true);\n commit(Mutations.SET_CACHE_CONNECTION, cachedClient.currentId);\n }\n },\n async [Actions.FETCH_DATA]({ commit }) {\n const initInfo = await httpApi('/info/init', null, 'GET');\n if (!('noConfig' in initInfo)) {\n commit(Mutations.SET_SCHEMAS, initInfo.schemas);\n commit(Mutations.SET_ROLES, initInfo.roles);\n }\n return initInfo;\n },\n async [Actions.GET_INFO]({ commit }, { schemas }) {\n commit(Mutations.SELECT_SCHEMAS, schemas);\n const info = await httpApi('/info', { schemas });\n commit(Mutations.SET_INFO, info);\n },\n async [Actions.GET_GRANTS]({ commit }, { grantees }) {\n commit(Mutations.SELECT_ROLES, grantees);\n const grants = await httpApi('/grants', { grantees });\n commit(Mutations.SET_GRANTS, grants);\n },\n async [Actions.GET_CACHED_CONNECTIONS]({ commit }) {\n const connections = await httpApi('/cache/connections', null, 'GET');\n commit(Mutations.SET_CACHE_CONNECTION_LIST, connections);\n },\n async [Actions.NEW_CONNECTION]({ commit }, { connection }) {\n const { connections } = await httpApi('/cache/newConnection', {\n connection,\n });\n commit(Mutations.SET_CACHE_CONNECTION_LIST, connections);\n },\n async [Actions.REMOVE_CONNECTION]({ commit, state }) {\n const { connections } = await httpApi('/cache/removeConnection', {\n connectionId: state.config.cache.currentConnection,\n });\n commit(Mutations.SET_CACHE_CONNECTION_LIST, connections);\n commit(Mutations.SET_CACHE_CONNECTION, null);\n },\n async [Actions.SET_CONNECTION]({ commit, dispatch }, { connectionId }) {\n await httpApi('/cache/setConnection', { connectionId });\n commit(Mutations.RESET_SELECTED);\n commit(Mutations.SET_CACHE_CONNECTION, connectionId);\n dispatch(Actions.FETCH_DATA);\n },\n async [Actions.REFRESH_DATA]({ dispatch }, { schemas, grantees }) {\n await dispatch(Actions.GET_INFO, { schemas });\n await dispatch(Actions.GET_GRANTS, { grantees });\n await dispatch(Actions.FETCH_DATA);\n },\n async [Actions.RUN_QUERY](\n { dispatch, commit },\n { sql, schemas, grantees },\n ) {\n await httpApi('/info/query', { sql });\n commit(Mutations.ADD_QUERY_LOG, sql);\n dispatch(Actions.REFRESH_DATA, { schemas, grantees });\n },\n};\n","const API_ENDPOINT =\n process.env.NODE_ENV === 'production'\n ? '/api'\n : 'http://localhost:9876/api';\nexport const httpApi = async (\n endpoint: string,\n data: unknown,\n method = 'POST',\n) => {\n const isPost = method === 'POST';\n const headers: Record = isPost\n ? {\n 'Content-Type': 'application/json',\n }\n : {};\n const body = isPost ? JSON.stringify(data) : null;\n return await fetch(`${API_ENDPOINT}${endpoint}`, {\n method,\n headers,\n body,\n }).then((res) => res.json());\n};\n","\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nimport Vue from 'vue';\nimport ZFieldset from '@/components/layout/Fieldset.vue';\n\nimport ZCheckbox from '@/components/layout/Checkbox.vue';\nimport { toggleArrayMixin } from '@/utils/toggleArray';\nimport { Mutations } from '@/store/mutations';\nimport { mapState, mapGetters } from 'vuex';\nimport { Getters } from '@/store/getters';\nimport { State } from '../store/state';\nimport { Actions } from '../store/actions';\n\nexport default Vue.extend({\n name: 'nav-bar',\n mixins: [toggleArrayMixin],\n data() {\n return {\n ignorePg: [] as string[],\n selectedConnection: '',\n };\n },\n filters: {\n clientName: (config: any) =>\n `${config.user}@${config.host}:${config.port || 5422}/${config.database}`,\n },\n mounted() {\n if (this.$store.state.config.ignorePg) {\n this.ignorePg = ['Ignore PG roles'];\n }\n if (this.$store.state.config.cache.currentConnection) {\n this.selectedConnection = this.$store.state.config.cache.currentConnection;\n }\n },\n computed: {\n ...mapState({\n currentConnection: (state: State) => state.config.cache.currentConnection,\n }),\n ...mapGetters([Getters.CONNECTION_LIST]),\n },\n watch: {\n ignorePg(val, oldVal) {\n const hasIgnore = val.length > 0;\n this.$store.commit(Mutations.SET_CONFIG_IGNORE, hasIgnore);\n },\n },\n methods: {\n handleConnectionChange() {\n this.$store.dispatch(Actions.SET_CONNECTION, {\n connectionId: this.selectedConnection,\n });\n },\n handleRemoveConnection() {\n this.$store.dispatch(Actions.REMOVE_CONNECTION);\n },\n },\n components: {\n ZCheckbox,\n ZFieldset,\n },\n});\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./NavBar.vue?vue&type=script&lang=ts&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./NavBar.vue?vue&type=script&lang=ts&\"","import { render, staticRenderFns } from \"./NavBar.vue?vue&type=template&id=e63cdd90&lang=pug&\"\nimport script from \"./NavBar.vue?vue&type=script&lang=ts&\"\nexport * from \"./NavBar.vue?vue&type=script&lang=ts&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"bg-white m-3 rounded-lg pb-2\"},[_c('div',{staticClass:\"font-display flex items-center justify-between p-2\"},[_c('div',{class:_vm.titleClass,on:{\"click\":_vm.showBody}},[_vm._v(_vm._s(_vm.title))]),_c('div',[(_vm.hasCollapse)?_c('fa-icon',{staticClass:\"text-gray-400 cursor-pointer hover:text-gray-600\",attrs:{\"icon\":_vm.fontName},on:{\"click\":_vm.handleCollapse}}):_vm._e(),(_vm.hasClose)?_c('fa-icon',{staticClass:\"text-gray-400 cursor-pointer hover:text-gray-600\",attrs:{\"icon\":\"times-circle\"},on:{\"click\":function($event){return _vm.$emit(\"close-card\")}}}):_vm._e()],1)]),(!_vm.isCollapsed)?_c('div',{staticClass:\"font-body\"},[_vm._t(\"default\"),_vm._t(\"action\")],2):_vm._e()])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nimport Vue from 'vue';\nexport default Vue.extend({\n name: 'z-card',\n props: {\n title: String,\n collapsed: {\n type: Boolean,\n default: false,\n },\n hasCollapse: {\n type: Boolean,\n default: true,\n },\n hasClose: {\n type: Boolean,\n default: false,\n },\n },\n mounted() {\n this.isCollapsed = this.collapsed;\n },\n data() {\n return {\n isCollapsed: false,\n };\n },\n computed: {\n fontName(): string {\n return !this.isCollapsed ? 'minus-circle' : 'plus-circle';\n },\n titleClass(): Record {\n return {\n 'text-gray-800': !this.isCollapsed,\n 'text-gray-600 cursor-pointer': this.isCollapsed,\n };\n },\n },\n methods: {\n handleCollapse() {\n this.isCollapsed = !this.isCollapsed;\n },\n showBody() {\n if (this.isCollapsed) {\n this.handleCollapse();\n }\n },\n },\n});\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Card.vue?vue&type=script&lang=ts&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Card.vue?vue&type=script&lang=ts&\"","import { render, staticRenderFns } from \"./Card.vue?vue&type=template&id=83f01c60&lang=pug&\"\nimport script from \"./Card.vue?vue&type=script&lang=ts&\"\nexport * from \"./Card.vue?vue&type=script&lang=ts&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"flex items-center\"},[(_vm.hasGrants)?_vm._l((_vm.entityGrants),function(grant,index){return _c('div',{directives:[{name:\"tooltip\",rawName:\"v-tooltip\",value:(grant),expression:\"grant\"}],key:index,staticClass:\"text-xs h-5 w-4 text-white mr-1 rounded-sm text-center select-none\",class:_vm.grantClass(grant),on:{\"click\":function($event){return _vm.handleGrantClick(grant)}}},[_vm._v(_vm._s(grant.slice(0, 1)))])}):[_c('div',{staticClass:\"w-10 h-1 bg-gray-400 rounded\"})]],2)}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n\n\n\n\n\nimport Vue from 'vue';\nimport { EntityTypes, EntityMeta } from '@/store/getters';\nexport default Vue.extend({\n name: 'z-entity-grant',\n props: {\n type: String as () => EntityTypes,\n grants: Array as () => string[],\n entity: Object as () => any,\n role: String,\n meta: Object as () => EntityMeta,\n },\n data() {\n return {\n allGrants: {\n [EntityTypes.TABLE]: [\n 'SELECT',\n 'INSERT',\n 'UPDATE',\n 'DELETE',\n 'TRUNCATE',\n 'REFERENCES',\n 'TRIGGER',\n ],\n [EntityTypes.COLUMN]: ['SELECT', 'INSERT', 'UPDATE', 'REFERENCES'],\n [EntityTypes.OBJECT]: ['USAGE'],\n [EntityTypes.ROUTINE]: ['EXECUTE'],\n [EntityTypes.TRIGGER]: [],\n },\n };\n },\n computed: {\n entityGrants(): string[] {\n return this.allGrants[this.type];\n },\n hasGrants(): boolean {\n return this.entityGrants.length > 0;\n },\n },\n methods: {\n hasGrant(grant: string): boolean {\n return this.grants.includes(grant);\n },\n grantClass(grant: string) {\n return {\n 'bg-green-400 hover:bg-green-500': this.hasGrant(grant),\n 'bg-gray-400 hover:bg-gray-500': !this.hasGrant(grant),\n };\n },\n handleGrantClick(grant: string) {\n const eventName = this.hasGrant(grant) ? 'revoke-grant' : 'allow-grant';\n\n const grantAction = this.hasGrant(grant) ? 'REVOKE' : 'GRANT';\n const grantPronoun = this.hasGrant(grant) ? 'FROM' : 'TO';\n const sqlQuery = this.meta.sql\n .replace('{:action}', grantAction)\n .replace('{:grant}', grant)\n .concat(` ${grantPronoun} ${this.role}`);\n\n this.$emit('run-query', sqlQuery);\n },\n },\n});\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./EntityGrant.vue?vue&type=script&lang=ts&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./EntityGrant.vue?vue&type=script&lang=ts&\"","import { render, staticRenderFns } from \"./EntityGrant.vue?vue&type=template&id=dc568c16&lang=pug&\"\nimport script from \"./EntityGrant.vue?vue&type=script&lang=ts&\"\nexport * from \"./EntityGrant.vue?vue&type=script&lang=ts&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"flex rounded items-center mt-1\",class:_vm.wrapClass},[_c('div',{staticClass:\"w-header__title\",class:_vm.titleStyle},[_c('div',{staticClass:\"row__head w-100 text-gray-600 bg-gray-300 select-none\",class:_vm.titleFont},[_c('fa-icon',{directives:[{name:\"tooltip\",rawName:\"v-tooltip\",value:(_vm.type),expression:\"type\"}],staticClass:\"mr-2\",attrs:{\"icon\":_vm.iconFont}}),_vm._v(_vm._s(_vm.title)),(_vm.hasMeta)?_c('span',{staticClass:\"text-xs ml-2 bg-gray-500 text-gray-800 p-1 rounded\"},[_vm._v(_vm._s(Object.values(_vm.meta).join(\" \")))]):_vm._e()],1)]),_c('div',{staticClass:\"row__data flex justify-around p-2 flex-grow text-gray-700 bg-gray-200 rounded-r\",class:_vm.slotClass},[_vm._t(\"default\")],2)])}\nvar staticRenderFns = []\n\nexport { render, staticRenderFns }","\n\n\n\n\n\n\n\n\n\n\n\n\n\nimport Vue from 'vue';\nimport { EntityTypes } from '@/store/getters';\n\nexport default Vue.extend({\n name: 'z-manage-row',\n props: {\n title: String,\n type: String as () => EntityTypes | 'header',\n meta: {\n type: Object as () => any,\n default: undefined,\n },\n level: {\n type: Number,\n default: 0,\n },\n isSticky: {\n type: Boolean,\n default: false,\n },\n },\n computed: {\n hasMeta(): boolean {\n if (this.meta && 'sql' in this.meta) {\n return false;\n }\n return this.meta !== undefined;\n },\n iconFont(): string {\n const fontMap = new Map([\n [EntityTypes.TABLE, 'table'],\n [EntityTypes.COLUMN, 'columns'],\n [EntityTypes.ROUTINE, 'code'],\n [EntityTypes.TRIGGER, 'bolt'],\n [EntityTypes.OBJECT, 'box'],\n ['header', 'users'],\n ]);\n return fontMap.get(this.type)!;\n },\n titleStyle(): Record {\n return {\n 'pl-0': this.level === 0,\n 'pl-4': this.level === 1,\n 'pl-8': this.level === 2,\n };\n },\n titleFont(): Record {\n return {\n 'text-sm': this.level > 0,\n 'bg-gray-400 text-gray-700': this.level === 0,\n 'bg-gray-300': this.level === 1,\n 'rounded-l': !this.isSticky,\n 'rounded-tl': this.isSticky,\n 'h-10 p-2': this.level === 0,\n 'h-8 p-1 pl-2': this.level > 0,\n };\n },\n slotClass(): Record {\n return {\n 'rounded-r': !this.isSticky,\n 'rounded-tr': this.isSticky,\n 'h-10': this.level === 0,\n 'h-8': this.level > 0,\n };\n },\n wrapClass(): Record {\n return {\n 'border-b-4 border-gray-500': this.isSticky,\n row__hover: this.type !== 'header',\n };\n },\n },\n});\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ManageRow.vue?vue&type=script&lang=ts&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ManageRow.vue?vue&type=script&lang=ts&\"","import { render, staticRenderFns } from \"./ManageRow.vue?vue&type=template&id=3faa052b&lang=pug&\"\nimport script from \"./ManageRow.vue?vue&type=script&lang=ts&\"\nexport * from \"./ManageRow.vue?vue&type=script&lang=ts&\"\nimport style0 from \"./ManageRow.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('form',{staticClass:\"px-2\",on:{\"submit\":function($event){$event.preventDefault();return _vm.addNewConnection($event)}}},[_c('div',{staticClass:\"flex justify-between\"},[_c('z-fieldset',{staticClass:\"mr-2 w-1/2\",attrs:{\"label\":\"User\"}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.connection.user),expression:\"connection.user\"}],staticClass:\"input--basic\",attrs:{\"type\":\"text\",\"required\":\"\"},domProps:{\"value\":(_vm.connection.user)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.$set(_vm.connection, \"user\", $event.target.value)}}})]),_c('z-fieldset',{staticClass:\"w-1/2\",attrs:{\"label\":\"Password\"}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.connection.password),expression:\"connection.password\"}],staticClass:\"input--basic\",attrs:{\"type\":\"password\",\"required\":\"\"},domProps:{\"value\":(_vm.connection.password)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.$set(_vm.connection, \"password\", $event.target.value)}}})])],1),_c('div',{staticClass:\"flex justify-between\"},[_c('z-fieldset',{staticClass:\"mr-2 w-1/2\",attrs:{\"label\":\"Host\"}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.connection.host),expression:\"connection.host\"}],staticClass:\"input--basic\",attrs:{\"type\":\"text\",\"placeholder\":\"127.0.0.1\",\"required\":\"\"},domProps:{\"value\":(_vm.connection.host)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.$set(_vm.connection, \"host\", $event.target.value)}}})]),_c('z-fieldset',{staticClass:\"w-1/2\",attrs:{\"label\":\"Port\"}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model.number\",value:(_vm.connection.port),expression:\"connection.port\",modifiers:{\"number\":true}}],staticClass:\"input--basic\",attrs:{\"type\":\"number\",\"placeholder\":\"5432\",\"required\":\"\"},domProps:{\"value\":(_vm.connection.port)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.$set(_vm.connection, \"port\", _vm._n($event.target.value))},\"blur\":function($event){return _vm.$forceUpdate()}}})])],1),_c('div',{staticClass:\"w-full\"},[_c('z-fieldset',{attrs:{\"label\":\"Database\"}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.connection.database),expression:\"connection.database\"}],staticClass:\"input--basic\",attrs:{\"type\":\"text\",\"required\":\"\"},domProps:{\"value\":(_vm.connection.database)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.$set(_vm.connection, \"database\", $event.target.value)}}})])],1),_vm._m(0)])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"action__bar mt-2 border-t\"},[_c('div',{staticClass:\"py-2\"},[_c('button',{staticClass:\"button--basic\",attrs:{\"type\":\"submit\"}},[_vm._v(\"Add\")])])])}]\n\nexport { render, staticRenderFns }","\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nimport Vue from 'vue';\n\nimport ZFieldset from '@/components/layout/Fieldset.vue';\nimport { Actions } from '../store/actions';\nexport default Vue.extend({\n name: 'z-form-connection',\n data() {\n return {\n connection: {\n user: '',\n password: '',\n host: '',\n port: '',\n database: '',\n },\n };\n },\n methods: {\n addNewConnection() {\n this.$store.dispatch(Actions.NEW_CONNECTION, {\n connection: this.connection,\n });\n this.connection = {\n user: '',\n password: '',\n host: '',\n port: '',\n database: '',\n };\n },\n },\n components: {\n ZFieldset,\n },\n});\n","import mod from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FormConnection.vue?vue&type=script&lang=ts&\"; export default mod; export * from \"-!../../node_modules/cache-loader/dist/cjs.js??ref--13-0!../../node_modules/thread-loader/dist/cjs.js!../../node_modules/babel-loader/lib/index.js!../../node_modules/ts-loader/index.js??ref--13-3!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./FormConnection.vue?vue&type=script&lang=ts&\"","import { render, staticRenderFns } from \"./FormConnection.vue?vue&type=template&id=7333d458&lang=pug&\"\nimport script from \"./FormConnection.vue?vue&type=script&lang=ts&\"\nexport * from \"./FormConnection.vue?vue&type=script&lang=ts&\"\n\n\n/* normalize component */\nimport normalizer from \"!../../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nimport Vue from 'vue';\nimport draggable from 'vuedraggable';\n\nimport NavBar from '@/components/NavBar.vue';\nimport ZCheckbox from '@/components/layout/Checkbox.vue';\nimport ZCard from '@/components/Card.vue';\nimport ZEntityGrant from '@/components/EntityGrant.vue';\nimport ZManageRow from '@/components/ManageRow.vue';\nimport ZFieldset from '@/components/layout/Fieldset.vue';\nimport ZFormConnection from '@/components/FormConnection.vue';\n\nimport { mapState, mapGetters, Dictionary } from 'vuex';\nimport { toggleArrayMixin } from '@/utils/toggleArray';\nimport { InformationSchema } from '@/utils/@types-information';\nimport { State, Computed } from '@/store/state';\nimport { Actions } from '@/store/actions';\nimport { Getters } from '@/store/getters';\nimport { Mutations } from '@/store/mutations';\nimport { EntityTypes, EntityRow } from '@/store/getters';\n\ninterface ComputedGetters {\n entityTree(): EntityRow[];\n schemaList(): string[];\n roleList(): string[];\n}\n\nexport default Vue.extend({\n name: 'app',\n mixins: [toggleArrayMixin],\n async mounted() {\n const initResponse = await this.$store.dispatch(Actions.INIT);\n if (!('noConfig' in initResponse)) {\n this.selectedRoles = this.selected.roles;\n this.selectedSchemas = this.selected.schemas;\n } else {\n this.app.noConfig = true;\n this.app.showAddConnection = true;\n }\n const THRESHOLD = 375;\n window.addEventListener(\n 'scroll',\n (ev) => {\n if (window.scrollY > 337) {\n this.app.showStickyHeader = true;\n } else {\n this.app.showStickyHeader = false;\n }\n },\n { passive: true },\n );\n },\n data() {\n return {\n selectedRoles: [] as string[],\n selectedSchemas: [] as string[],\n selectedEntities: [\n 'Tables',\n 'Columns',\n 'Objects',\n 'Routines',\n 'Triggers',\n ],\n app: {\n showStickyHeader: false,\n showQueryLog: false,\n showAddConnection: false,\n noConfig: true,\n },\n config: {\n manage: [\n {\n label: 'Tables',\n value: EntityTypes.TABLE,\n },\n {\n label: 'Columns',\n value: EntityTypes.COLUMN,\n },\n {\n label: 'Objects',\n value: EntityTypes.OBJECT,\n },\n {\n label: 'Routines',\n value: EntityTypes.ROUTINE,\n },\n {\n label: 'Triggers',\n value: EntityTypes.TRIGGER,\n },\n ],\n },\n filterCache: [] as any[],\n entityForm: {\n name: '',\n type: 'ROLE',\n },\n };\n },\n watch: {\n selectedSchemas(val, oldVal) {\n if (val.length) {\n this.$store.dispatch(Actions.GET_INFO, { schemas: val });\n }\n },\n selectedRoles(val, oldVal) {\n if (val.length) {\n this.$store.dispatch(Actions.GET_GRANTS, { grantees: val });\n }\n },\n },\n computed: {\n ...((mapState([\n 'init',\n 'selected',\n 'queryLog',\n ]) as unknown) as Computed),\n ...((mapGetters([\n Getters.ENTITY_TREE,\n Getters.SCHEMA_LIST,\n Getters.ROLE_LIST,\n ]) as unknown) as ComputedGetters),\n\n hasSelected(): boolean {\n return this.selectedSchemas.length > 0 && this.selectedRoles.length > 0;\n },\n headerClass(): Record {\n return {\n 'fixed w-header top-0 mt-1': this.app.showStickyHeader,\n 'w-full': !this.app.showStickyHeader,\n };\n },\n filteredEntities(): EntityRow[] {\n const entityTypes = this.config.manage\n .filter((m) => this.selectedEntities.includes(m.label))\n .map((m) => m.value);\n return this.entityTree.filter((e) => entityTypes.includes(e.type));\n },\n },\n methods: {\n runQuery(sql: string): void {\n this.$store.dispatch(Actions.RUN_QUERY, {\n sql,\n schemas: this.selectedSchemas,\n grantees: this.selectedRoles,\n });\n },\n handleAddEntity(): void {\n const sql = `CREATE ${this.entityForm.type} ${this.entityForm.name}`;\n const schemas = this.selectedSchemas || [];\n const grantees = this.selectedRoles || [];\n this.$store.dispatch(Actions.RUN_QUERY, {\n sql,\n schemas,\n grantees,\n });\n this.entityForm.name = '';\n },\n },\n components: {\n NavBar,\n ZCheckbox,\n ZCard,\n ZEntityGrant,\n ZManageRow,\n ZFieldset,\n ZFormConnection,\n draggable,\n },\n});\n","import mod from \"-!../node_modules/cache-loader/dist/cjs.js??ref--13-0!../node_modules/thread-loader/dist/cjs.js!../node_modules/babel-loader/lib/index.js!../node_modules/ts-loader/index.js??ref--13-3!../node_modules/cache-loader/dist/cjs.js??ref--0-0!../node_modules/vue-loader/lib/index.js??vue-loader-options!./App.vue?vue&type=script&lang=ts&\"; export default mod; export * from \"-!../node_modules/cache-loader/dist/cjs.js??ref--13-0!../node_modules/thread-loader/dist/cjs.js!../node_modules/babel-loader/lib/index.js!../node_modules/ts-loader/index.js??ref--13-3!../node_modules/cache-loader/dist/cjs.js??ref--0-0!../node_modules/vue-loader/lib/index.js??vue-loader-options!./App.vue?vue&type=script&lang=ts&\"","import { render, staticRenderFns } from \"./App.vue?vue&type=template&id=85362926&lang=pug&\"\nimport script from \"./App.vue?vue&type=script&lang=ts&\"\nexport * from \"./App.vue?vue&type=script&lang=ts&\"\nimport style0 from \"./App.vue?vue&type=style&index=0&lang=css&\"\n\n\n/* normalize component */\nimport normalizer from \"!../node_modules/vue-loader/lib/runtime/componentNormalizer.js\"\nvar component = normalizer(\n script,\n render,\n staticRenderFns,\n false,\n null,\n null,\n null\n \n)\n\nexport default component.exports","import { InformationSchema } from '@/utils/@types-information';\ninterface StateConfig {\n cache: {\n hasCached: boolean;\n currentConnection: string | null;\n connectionList: Record | null;\n };\n ignorePg: boolean;\n}\ninterface StateInit {\n schemas: string[];\n roles: string[];\n}\ninterface StateInfo {\n columns: InformationSchema.Default.Column[];\n roles: string[];\n tables: InformationSchema.Default.Table[];\n triggers: InformationSchema.Default.Trigger[];\n routines: InformationSchema.Default.Routine[];\n}\ninterface StateGrants {\n columns: InformationSchema.Grants.Column[];\n objects: InformationSchema.Grants.Usage[];\n routines: InformationSchema.Grants.Routine[];\n tables: InformationSchema.Grants.Table[];\n}\ninterface QueryLog {\n sql: string;\n date: Date;\n}\nexport interface State {\n config: StateConfig;\n selected: StateInit;\n init: StateInit;\n info: StateInfo;\n grants: StateGrants;\n refreshTable: boolean;\n queryLog: QueryLog[];\n}\nexport type Computed = { [K in keyof T]: () => T[K] };\nexport const state: State = {\n refreshTable: false,\n config: {\n ignorePg: true,\n cache: {\n hasCached: false,\n currentConnection: null,\n connectionList: null,\n },\n },\n selected: {\n schemas: [],\n roles: [],\n },\n init: {\n schemas: [],\n roles: [],\n },\n info: {\n columns: [],\n roles: [],\n tables: [],\n triggers: [],\n routines: [],\n },\n grants: {\n columns: [],\n objects: [],\n routines: [],\n tables: [],\n },\n queryLog: [],\n};\n","import Vue from 'vue';\nimport Vuex from 'vuex';\nimport VuexPersistence from 'vuex-persist';\n\nimport { state, State } from './state';\nimport { actions } from './actions';\nimport { mutations } from './mutations';\nimport { getters } from './getters';\nVue.use(Vuex);\n\nconst vuexLocal = new VuexPersistence({\n storage: window.localStorage,\n reducer: (s) => ({ config: s.config, selected: s.selected }),\n});\nexport default new Vuex.Store({\n state,\n mutations,\n actions,\n getters,\n plugins: [vuexLocal.plugin],\n});\n","import Vue from 'vue';\nimport App from './App.vue';\nimport store from './store/index';\nimport 'animate.css';\nimport '@/assets/css/tailwind.css';\nimport '@/assets/css/v-tooltip.css';\nimport '@/assets/css/main.css';\nimport VTooltip from 'v-tooltip';\n\nimport { library } from '@fortawesome/fontawesome-svg-core';\nimport {\n faCheckCircle,\n faSync,\n faTable,\n faColumns,\n faCode,\n faBolt,\n faBox,\n faUsers,\n faMinusCircle,\n faPlusCircle,\n faBars,\n faCaretRight,\n faArrowRight,\n faTimesCircle,\n faPlus,\n faExclamationTriangle,\n faTrash,\n} from '@fortawesome/free-solid-svg-icons';\nimport { faCircle } from '@fortawesome/free-regular-svg-icons';\nimport { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';\n\nlibrary.add(\n faCheckCircle,\n faCircle,\n faSync,\n faTable,\n faColumns,\n faCode,\n faBolt,\n faBox,\n faUsers,\n faMinusCircle,\n faPlusCircle,\n faBars,\n faCaretRight,\n faArrowRight,\n faTimesCircle,\n faPlus,\n faExclamationTriangle,\n faTrash,\n);\nVue.use(VTooltip);\n\nVue.component('fa-icon', FontAwesomeIcon);\nVue.config.productionTip = false;\nnew Vue({\n store,\n render: (h) => h(App),\n}).$mount('#app');\n","import mod from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ManageRow.vue?vue&type=style&index=0&lang=css&\"; export default mod; export * from \"-!../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../node_modules/vue-loader/lib/index.js??vue-loader-options!./ManageRow.vue?vue&type=style&index=0&lang=css&\"","import mod from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Checkbox.vue?vue&type=style&index=0&id=eab987ae&scoped=true&lang=css&\"; export default mod; export * from \"-!../../../node_modules/mini-css-extract-plugin/dist/loader.js??ref--6-oneOf-1-0!../../../node_modules/css-loader/index.js??ref--6-oneOf-1-1!../../../node_modules/vue-loader/lib/loaders/stylePostLoader.js!../../../node_modules/postcss-loader/src/index.js??ref--6-oneOf-1-2!../../../node_modules/cache-loader/dist/cjs.js??ref--0-0!../../../node_modules/vue-loader/lib/index.js??vue-loader-options!./Checkbox.vue?vue&type=style&index=0&id=eab987ae&scoped=true&lang=css&\""],"sourceRoot":""}
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "postgres-hr",
3 | "version": "0.0.21",
4 | "description": "Manage Postgres roles in a sane way",
5 | "main": "build/server.js",
6 | "scripts": {
7 | "dev": "PORT=9876 nodemon build/server.js --ignore 'postgres-hr.json'",
8 | "tsc:w": "tsc --watch",
9 | "build": "tsc",
10 | "test": "echo \"Error: no test specified\" && exit 1",
11 | "prepack": "npm run build"
12 | },
13 | "bin": {
14 | "postgres-hr": "./build/server.js"
15 | },
16 | "keywords": [
17 | "postgres",
18 | "postgresql",
19 | "roles",
20 | "role management",
21 | "gui",
22 | "rbac"
23 | ],
24 | "author": "butttons",
25 | "license": "MIT",
26 | "dependencies": {
27 | "body-parser": "^1.19.0",
28 | "cors": "^2.8.5",
29 | "express": "^4.17.1",
30 | "knex": "^0.21.17",
31 | "lodash.isequal": "^4.5.0",
32 | "lowdb": "^1.0.0",
33 | "module-alias": "^2.2.0",
34 | "pg": "^8.5.1",
35 | "platform-folders": "^0.5.2",
36 | "reflect-metadata": "^0.1.10",
37 | "shortid": "^2.2.15"
38 | },
39 | "devDependencies": {
40 | "@types/express": "^4.17.1",
41 | "@types/lodash": "^4.14.141",
42 | "@types/lodash.isequal": "^4.5.5",
43 | "@types/lowdb": "^1.0.9",
44 | "@types/node": "^8.0.29",
45 | "@types/pg": "^7.14.9",
46 | "typescript": "^3.5.3"
47 | },
48 | "_moduleAliases": {
49 | "@": "build"
50 | },
51 | "repository": {
52 | "type": "git",
53 | "url": "git+https://github.com/butttons/postgres-hr"
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/api/index.ts:
--------------------------------------------------------------------------------
1 | import { Router } from 'express';
2 | import bodyParser from 'body-parser';
3 | import { info } from './routes/info';
4 | import { cache } from './routes/cache';
5 | import { grants } from './routes/grants';
6 |
7 | export const api = Router();
8 | api.use(bodyParser.json());
9 | api.use('/info', info);
10 | api.use('/cache', cache);
11 | api.use('/grants', grants);
12 |
--------------------------------------------------------------------------------
/src/api/routes/cache.ts:
--------------------------------------------------------------------------------
1 | import { Router } from 'express';
2 | import { cacheDb } from '@/utils/cache-db/lowdb';
3 | import { ConnectionConfig } from 'pg';
4 | import isEqual from 'lodash.isequal';
5 | export const cache = Router();
6 | import shortid from 'shortid';
7 |
8 | const hasCachedConnection = (connection: ConnectionConfig) => {
9 | const connections = cacheDb.get('connections').value();
10 | const cachedConnection = Object.values(connections).find((c) =>
11 | isEqual(c, connection),
12 | );
13 | const hasConnection = cachedConnection !== undefined;
14 | return hasConnection;
15 | };
16 | const addConnection = (connection: ConnectionConfig) => {
17 | const connections = cacheDb.get('connections');
18 | const newId = shortid();
19 | connections.set(newId, connection).write();
20 | return newId;
21 | };
22 | const allConnections = () => cacheDb.get('connections').value();
23 | const removeConnection = (connectionId: string) => {
24 | cacheDb.get('connections').unset(connectionId).write();
25 | cacheDb.set('currentConnection', null).write();
26 | };
27 |
28 | cache.get('/connections', (req, res) => {
29 | const connections = allConnections();
30 | res.json(connections);
31 | });
32 | cache.get('/current', (req, res) => {
33 | const currentId = cacheDb.get('currentConnection').value();
34 | res.json({ currentId });
35 | });
36 | cache.post('/newConnection', (req, res) => {
37 | const newConnection = req.body.connection;
38 | const hasConnection = hasCachedConnection(newConnection);
39 | if (!hasConnection) {
40 | addConnection(newConnection);
41 | const connections = allConnections();
42 | res.json({ connections, status: { success: true } });
43 | return;
44 | }
45 | const connections = allConnections();
46 | res.json({ connections, status: { success: true } });
47 | });
48 | cache.post('/removeConnection', (req, res) => {
49 | const connectionId = req.body.connectionId;
50 | removeConnection(connectionId);
51 | const connections = allConnections();
52 | res.json({ connections, status: { success: true } });
53 | });
54 | cache.post('/setConnection', (req, res) => {
55 | const connectionId = req.body.connectionId;
56 | cacheDb.set('currentConnection', connectionId).write();
57 | res.json({ connectionId });
58 | });
59 |
--------------------------------------------------------------------------------
/src/api/routes/grants.ts:
--------------------------------------------------------------------------------
1 | import { Router } from 'express';
2 | import { utilsFactory } from '@/utils/api-factories';
3 | import { clientFactory } from '@/utils/pg';
4 | import { InformationSchema } from '@/utils/@types-information';
5 | import { generateList } from '@/utils/generate-list';
6 | export const grants = Router();
7 |
8 | grants.post('/', async (req, res) => {
9 | const { getGrants } = utilsFactory(clientFactory());
10 | const grantees = req.body.grantees;
11 | const [columns, objects, routines, tables] = await Promise.all([
12 | getGrants(grantees, InformationSchema.TableNames.RoleGrants.COLUMN),
13 | getGrants(grantees, InformationSchema.TableNames.RoleGrants.OBJECT),
14 | getGrants(grantees, InformationSchema.TableNames.RoleGrants.ROUTINE),
15 | getGrants(grantees, InformationSchema.TableNames.RoleGrants.TABLE),
16 | ]);
17 |
18 | res.json({
19 | columns,
20 | objects,
21 | routines,
22 | tables,
23 | });
24 | });
25 | grants.post('/list', async (req, res) => {
26 | const { allInfo, allGrants } = utilsFactory(clientFactory());
27 | const { schemas, grantees } = req.body;
28 | const [info, grants] = await Promise.all([
29 | allInfo(schemas),
30 | allGrants(grantees),
31 | ]);
32 |
33 | const list = generateList(info, grants, grantees);
34 | res.json({ list });
35 | });
36 |
--------------------------------------------------------------------------------
/src/api/routes/info.ts:
--------------------------------------------------------------------------------
1 | import { Router } from 'express';
2 | import { utilsFactory } from '@/utils/api-factories';
3 | import { clientFactory } from '@/utils/pg';
4 |
5 | export const info = Router();
6 |
7 | info.post('/', async (req, res) => {
8 | const client = await clientFactory();
9 | const {
10 | allColumns,
11 | allRoles,
12 | allTables,
13 | allTriggers,
14 | allRoutines,
15 | } = utilsFactory(client);
16 | const schemas = req.body.schemas;
17 | const [columns, roles, tables, triggers, routines] = await Promise.all([
18 | allColumns(schemas),
19 | allRoles(),
20 | allTables(schemas),
21 | allTriggers(schemas),
22 | allRoutines(schemas),
23 | ]);
24 | res.json({
25 | columns,
26 | roles,
27 | tables,
28 | triggers,
29 | routines,
30 | });
31 | });
32 | info.get('/init', async (req, res) => {
33 | const client = clientFactory();
34 | if (client === null) {
35 | res.json({ noConfig: true });
36 | return;
37 | }
38 | const { allSchemas, allRoles } = utilsFactory(client);
39 | const [schemas, roles] = await Promise.all([allSchemas(), allRoles()]);
40 | res.json({
41 | schemas,
42 | roles,
43 | });
44 | });
45 |
46 | info.post('/query', async (req, res) => {
47 | const query = req.body.sql;
48 | const client = clientFactory();
49 | await client.query(query);
50 | res.send({ success: true });
51 | });
52 |
--------------------------------------------------------------------------------
/src/app.ts:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import { api } from './api';
3 |
4 | import cors from 'cors';
5 | import { resolve } from 'path';
6 | export const app = express();
7 |
8 | const uiDir = resolve(__dirname, '..', 'dist');
9 |
10 | app.use(cors('*'));
11 | app.use('/api', api);
12 |
13 | app.use(express.static(uiDir));
14 |
--------------------------------------------------------------------------------
/src/server.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | require('module-alias/register');
4 | import { createServer } from 'http';
5 | import { app } from './app';
6 | const server = createServer(app);
7 |
8 | const port = +process.env.PORT || 9876;
9 | server.listen(port, () =>
10 | console.log(`PostgresHR available at -- http://localhost:${port}`),
11 | );
12 |
--------------------------------------------------------------------------------
/src/shims-lowdb.d.ts:
--------------------------------------------------------------------------------
1 | declare namespace Lowdb {}
2 |
--------------------------------------------------------------------------------
/src/utils/@types-information.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable */
2 | export type Maybe = T | null;
3 | interface BaseGrant {
4 | grantor: string;
5 | grantee: string;
6 | privilege_type: string;
7 | is_grantable: InformationSchema.Types.YesOrNo;
8 | }
9 | export module InformationSchema {
10 | // Table names of relevant tables that we need.
11 | export module TableNames {
12 | export const enum RoleGrants {
13 | COLUMN = 'column_privileges',
14 | ROUTINE = 'routine_privileges',
15 | TABLE = 'table_privileges',
16 | OBJECT = 'usage_privileges',
17 | }
18 | export const enum InfoTables {
19 | TABLE = 'tables',
20 | COLUMN = 'columns',
21 | TRIGGER = 'triggers',
22 | }
23 | }
24 | // Possible privileges on each type of entity.
25 | export module Privileges {
26 | export type Column = 'SELECT' | 'INSERT' | 'UPDATE' | 'REFERENCES';
27 | export type Routine = 'EXECUTE';
28 | export type Table =
29 | | 'SELECT'
30 | | 'INSERT'
31 | | 'UPDATE'
32 | | 'DELETE'
33 | | 'TRUNCATE'
34 | | 'REFERENCES'
35 | | 'TRIGGER';
36 | export type Usage = 'USAGE';
37 | }
38 | // Possible data types of each entity.
39 | export module Types {
40 | export type YesOrNo = 'YES' | 'NO';
41 | export type Trigger = 'INSERT' | 'UPDATE' | 'DELETE';
42 | export type Routine = 'FUNCTION' | 'PROCEDURE';
43 | export type Object =
44 | | 'COLLATION'
45 | | 'DOMAIN'
46 | | 'FOREIGN DATA WRAPPER'
47 | | 'FOREIGN SERVER'
48 | | 'SEQUENCE';
49 | }
50 | // The shape of the default tables we need to query.
51 | export module Default {
52 | export interface Table {
53 | table_schema: string;
54 | table_name: string;
55 | table_type: string;
56 | }
57 | export interface Column {
58 | table_schema: string;
59 | table_name: string;
60 | column_name: string;
61 | ordinal_position: number;
62 | column_default: string;
63 | is_nullable: Types.YesOrNo;
64 | data_type: string;
65 | is_identity: Types.YesOrNo;
66 | }
67 | export interface Trigger {
68 | trigger_catalog: string;
69 | trigger_schema: string;
70 | trigger_name: string;
71 | event_manipulation: Types.Trigger;
72 | event_object_catalog: string;
73 | event_object_schema: string;
74 | event_object_table: string;
75 | action_order: number;
76 | action_condition: string;
77 | action_statement: string;
78 | action_orientation: string;
79 | action_timing: string;
80 | action_reference_old_table: Maybe;
81 | action_reference_new_table: Maybe;
82 | action_reference_old_row: null;
83 | action_reference_new_row: null;
84 | created: null;
85 | }
86 | export interface Routine {
87 | specific_schema: string;
88 | routine_schema: string;
89 | routine_name: string;
90 | routine_type: Types.Routine;
91 | data_type: string;
92 | }
93 | }
94 | // The shape of the grants table which give information regarding privileges of each entity.
95 | export module Grants {
96 | export interface Column extends BaseGrant {
97 | table_catalog: string;
98 | table_schema: string;
99 | table_name: string;
100 | column_name: string;
101 | privilege_type: Privileges.Column;
102 | }
103 | export interface Routine extends BaseGrant {
104 | specific_catalog: string;
105 | specific_schema: string;
106 | specific_name: string;
107 | routine_catalog: string;
108 | routine_schema: string;
109 | routine_name: string;
110 | privilege_type: Privileges.Routine;
111 | }
112 | export interface Table extends BaseGrant {
113 | table_catalog: string;
114 | table_schema: string;
115 | table_name: string;
116 | with_hierarchy: string;
117 | privilege_type: Privileges.Table;
118 | }
119 | export interface Usage extends BaseGrant {
120 | object_catalog: string;
121 | object_schema: string;
122 | object_name: string;
123 | object_type: Types.Object;
124 | privilege_type: Privileges.Usage;
125 | }
126 | }
127 | export type AllGrants =
128 | | Grants.Column
129 | | Grants.Routine
130 | | Grants.Table
131 | | Grants.Usage;
132 | }
133 |
--------------------------------------------------------------------------------
/src/utils/api-factories.ts:
--------------------------------------------------------------------------------
1 | import { Client, QueryResult } from 'pg';
2 | import { Maybe, InformationSchema } from './@types-information';
3 |
4 | const getArrayParams = (values: string[]) =>
5 | values.map((_, i) => `$${i + 1}`).join(', ');
6 | const fetchRows = (result: QueryResult) => result.rows;
7 | const catchError = (err: Error) => {
8 | console.warn('utilsFactory:', err);
9 | return null;
10 | };
11 | const selectWhereIn = (
12 | table: string,
13 | columns: string[],
14 | column: string,
15 | values: string[],
16 | ) => ({
17 | text: `SELECT ${columns.join(
18 | ',',
19 | )} FROM information_schema.${table} WHERE ${column} IN (${getArrayParams(
20 | values,
21 | )})`,
22 | values,
23 | });
24 | export interface TableInfo {
25 | tables: InformationSchema.Default.Table[];
26 | columns: InformationSchema.Default.Column[];
27 | triggers: InformationSchema.Default.Trigger[];
28 | routines: InformationSchema.Default.Routine[];
29 | roles: string[];
30 | }
31 | export interface GrantInfo {
32 | columnGrants: InformationSchema.Grants.Column[];
33 | objectGrants: InformationSchema.Grants.Usage[];
34 | routineGrants: InformationSchema.Grants.Routine[];
35 | tableGrants: InformationSchema.Grants.Table[];
36 | }
37 |
38 | const DEFAULT_TABLE_COLUMNS = ['table_schema', 'table_name'];
39 | export const utilsFactory = (client: Client) => ({
40 | getGrants: async (
41 | grantees: string[],
42 | table: InformationSchema.TableNames.RoleGrants,
43 | ): Promise> =>
44 | await client
45 | .query(selectWhereIn(table, ['*'], 'grantee', grantees))
46 | .then(fetchRows)
47 | .catch(catchError),
48 | allSchemas: async (): Promise> =>
49 | await client
50 | .query('SELECT schema_name FROM information_schema.schemata;')
51 | .then(fetchRows)
52 | .then((rows) => rows.map((r) => r.schema_name))
53 | .catch(catchError),
54 | allRoles: async (): Promise> =>
55 | await client
56 | .query('SELECT rolname FROM pg_roles')
57 | .then(fetchRows)
58 | .then((rows) => rows.map((r) => r.rolname))
59 | .catch(catchError),
60 | allTables: async (
61 | schemas: string[],
62 | ): Promise> =>
63 | await client
64 | .query(
65 | selectWhereIn(
66 | 'tables',
67 | [...DEFAULT_TABLE_COLUMNS, 'table_type'],
68 | 'table_schema',
69 | schemas,
70 | ),
71 | )
72 | .then(fetchRows)
73 | .catch(catchError),
74 | allColumns: async (
75 | schemas: string[],
76 | ): Promise> =>
77 | await client
78 | .query(
79 | selectWhereIn(
80 | 'columns',
81 | [
82 | ...DEFAULT_TABLE_COLUMNS,
83 | 'column_name',
84 | 'ordinal_position',
85 | 'column_default',
86 | 'is_nullable',
87 | 'data_type',
88 | 'dtd_identifier',
89 | 'is_identity',
90 | ],
91 | 'table_schema',
92 | schemas,
93 | ),
94 | )
95 | .then(fetchRows)
96 | .catch(catchError),
97 | allTriggers: async (
98 | schemas: string[],
99 | ): Promise> =>
100 | await client
101 | .query(selectWhereIn('triggers', ['*'], 'trigger_schema', schemas))
102 | .then(fetchRows)
103 | .catch(catchError),
104 | allRoutines: async (
105 | schemas: string[],
106 | ): Promise> =>
107 | await client
108 | .query(
109 | selectWhereIn(
110 | 'routines',
111 | [
112 | 'specific_name',
113 | 'routine_schema',
114 | 'routine_name',
115 | 'routine_type',
116 | 'data_type',
117 | ],
118 | 'specific_schema',
119 | schemas,
120 | ),
121 | )
122 | .then(fetchRows)
123 | .catch(catchError),
124 | allInfo: async (schemas: string[]): Promise => {
125 | const {
126 | allColumns,
127 | allRoles,
128 | allTables,
129 | allTriggers,
130 | allRoutines,
131 | } = utilsFactory(client);
132 | const [columns, roles, tables, triggers, routines] = await Promise.all([
133 | allColumns(schemas),
134 | allRoles(),
135 | allTables(schemas),
136 | allTriggers(schemas),
137 | allRoutines(schemas),
138 | ]);
139 | return { columns, roles, tables, triggers, routines };
140 | },
141 | allGrants: async (grantees: string[]): Promise => {
142 | const { getGrants } = utilsFactory(client);
143 | const [
144 | columnGrants,
145 | objectGrants,
146 | routineGrants,
147 | tableGrants,
148 | ] = await Promise.all([
149 | getGrants(
150 | grantees,
151 | InformationSchema.TableNames.RoleGrants.COLUMN,
152 | ) as Promise,
153 | getGrants(
154 | grantees,
155 | InformationSchema.TableNames.RoleGrants.OBJECT,
156 | ) as Promise,
157 | getGrants(
158 | grantees,
159 | InformationSchema.TableNames.RoleGrants.ROUTINE,
160 | ) as Promise,
161 | getGrants(
162 | grantees,
163 | InformationSchema.TableNames.RoleGrants.TABLE,
164 | ) as Promise,
165 | ]);
166 | return { columnGrants, objectGrants, routineGrants, tableGrants };
167 | },
168 | });
169 |
--------------------------------------------------------------------------------
/src/utils/cache-db/lowdb.ts:
--------------------------------------------------------------------------------
1 | import low from 'lowdb';
2 | import FileSync from 'lowdb/adapters/FileSync';
3 | import { resolve } from 'path';
4 | import { ConnectionConfig } from 'pg';
5 | import { getConfigHome } from 'platform-folders';
6 |
7 | export interface CacheSchema {
8 | connections: Record;
9 | currentConnection: string;
10 | }
11 | const dbFilePath = resolve(getConfigHome(), 'postgres-hr.json');
12 | const adapter = new FileSync(dbFilePath);
13 | export const cacheDb = low(adapter);
14 |
15 | cacheDb
16 | .defaults({
17 | connections: {},
18 | currentConnection: null,
19 | })
20 | .write();
21 |
--------------------------------------------------------------------------------
/src/utils/cache-db/utils.ts:
--------------------------------------------------------------------------------
1 | import { cacheDb } from './lowdb';
2 | export const currentConnectionConfig = () => {
3 | const id = cacheDb.get('currentConnection').value();
4 | const config = cacheDb.get('connections').get(id).value();
5 | return { config, id };
6 | };
7 |
--------------------------------------------------------------------------------
/src/utils/generate-list.ts:
--------------------------------------------------------------------------------
1 | import { TableInfo, GrantInfo } from './api-factories';
2 | import { InformationSchema } from './@types-information';
3 |
4 | export type EntityGrant = Record;
5 | export const enum EntityTypes {
6 | TABLE = 'table',
7 | COLUMN = 'column',
8 | ROUTINE = 'routine',
9 | OBJECT = 'object',
10 | TRIGGER = 'trigger',
11 | }
12 |
13 | interface EntityRow {
14 | type: EntityTypes;
15 | level: number;
16 | label: string;
17 | grants: EntityGrant;
18 | meta?: any;
19 | }
20 | const entityRow = (
21 | type: EntityTypes,
22 | label: string,
23 | grants: EntityGrant,
24 | level: number | null = null,
25 | meta?: any[],
26 | ): EntityRow => {
27 | const entityLevels = new Map([
28 | [EntityTypes.TABLE, 0],
29 | [EntityTypes.COLUMN, 1],
30 | [EntityTypes.ROUTINE, 2],
31 | [EntityTypes.TRIGGER, 1],
32 | [EntityTypes.OBJECT, 1],
33 | ]);
34 | return {
35 | type,
36 | label,
37 | grants,
38 | meta,
39 | level: level === null ? entityLevels.get(type)! : level,
40 | };
41 | };
42 | export const generateList = async (
43 | info: TableInfo,
44 | grants: GrantInfo,
45 | grantees: string[],
46 | ) => {
47 | const maps = {
48 | [EntityTypes.TABLE]: {},
49 | };
50 | };
51 |
--------------------------------------------------------------------------------
/src/utils/knex/connection.ts:
--------------------------------------------------------------------------------
1 | import knex from 'knex';
2 |
3 | export const db = knex({
4 | client: 'pg',
5 | connection: {
6 | user: 'postgres',
7 | host: 'localhost',
8 | database: 'hr_test',
9 | password: 'postgres',
10 | port: 5433,
11 | },
12 | });
13 |
--------------------------------------------------------------------------------
/src/utils/knex/schema.ts:
--------------------------------------------------------------------------------
1 | import { db } from './connection';
2 |
3 | const enum Schemas {
4 | PUBLIC = 'db_public',
5 | PRIVATE = 'db_private',
6 | }
7 |
8 | export const schemaGen = async () => {
9 | const { schema } = db;
10 | await schema.raw(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp";`);
11 | await schema
12 | .withSchema(Schemas.PUBLIC)
13 | .hasTable('user')
14 | .then(async (has) => {
15 | if (!has) {
16 | await schema.createTable('user', (table) => {
17 | table
18 | .uuid('id')
19 | .primary()
20 | .defaultTo(db.raw('uuid_generate_v4()'));
21 | table.string('name');
22 | table.date('date_of_birth');
23 | table.timestamps(true, true);
24 | });
25 | }
26 | });
27 | await schema
28 | .withSchema(Schemas.PUBLIC)
29 | .hasTable('post')
30 | .then(async (has) => {
31 | if (!has) {
32 | await schema.createTableIfNotExists('post', (table) => {
33 | table
34 | .uuid('id')
35 | .primary()
36 | .defaultTo(db.raw('uuid_generate_v4()'));
37 | table
38 | .uuid('user_id')
39 | .references('id')
40 | .inTable('db_public.user');
41 | table.string('title');
42 | table.string('description');
43 | table.timestamps(true, true);
44 | });
45 | }
46 | });
47 | };
48 |
--------------------------------------------------------------------------------
/src/utils/pg.ts:
--------------------------------------------------------------------------------
1 | import { Client } from 'pg';
2 | import { currentConnectionConfig } from '@/utils/cache-db/utils';
3 |
4 | const clientMap = new Map();
5 |
6 | export const clientFactory = (): Client | null => {
7 | const info = currentConnectionConfig();
8 | if (info.id === null) return null;
9 | if (clientMap.has(info.id)) {
10 | return clientMap.get(info.id);
11 | } else {
12 | const client = new Client(info.config);
13 | client.connect();
14 | clientMap.set(info.id, client);
15 | return client;
16 | }
17 | };
18 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "experimentalDecorators": true,
4 | "target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
5 | "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
6 | "lib": [
7 | "esnext"
8 | ] /* Specify library files to be included in the compilation. */,
9 | "allowJs": true,
10 | "moduleResolution": "node",
11 | "outDir": "./build",
12 | "rootDir": "./src",
13 | "emitDecoratorMetadata": true,
14 | "sourceMap": true,
15 | "allowSyntheticDefaultImports": true,
16 | "esModuleInterop": true,
17 | "baseUrl": ".",
18 | "resolveJsonModule": true,
19 | "paths": {
20 | "*": ["types/*"],
21 | "@/*": ["src/*"]
22 | }
23 | },
24 | "include": ["src/*"],
25 | "exclude": ["node_modules"]
26 | }
27 |
--------------------------------------------------------------------------------